@lifi/widget 4.4.0 → 4.6.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 (329) hide show
  1. package/dist/esm/App.js.map +1 -1
  2. package/dist/esm/AppDrawer.js +2 -1
  3. package/dist/esm/AppDrawer.js.map +1 -1
  4. package/dist/esm/AppLayout.js.map +1 -1
  5. package/dist/esm/AppProvider.js.map +1 -1
  6. package/dist/esm/components/ActionRow/ActionRow.js.map +1 -1
  7. package/dist/esm/components/AmountInput/AmountInput.js +13 -7
  8. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  9. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +2 -13
  10. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  11. package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
  12. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
  13. package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -1
  14. package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -1
  15. package/dist/esm/components/AmountInputCard/PercentageChips.js +2 -13
  16. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -1
  17. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +1 -1
  18. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -1
  19. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
  20. package/dist/esm/components/AmountInputCard/SendAmountCard.js +13 -6
  21. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -1
  22. package/dist/esm/components/AppContainer.js.map +1 -1
  23. package/dist/esm/components/Avatar/AccountAvatar.js.map +1 -1
  24. package/dist/esm/components/Avatar/Avatar.js.map +1 -1
  25. package/dist/esm/components/Avatar/ChainBadgeContent.js.map +1 -1
  26. package/dist/esm/components/Avatar/TokenAvatar.js.map +1 -1
  27. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
  28. package/dist/esm/components/Card/CardButton.js.map +1 -1
  29. package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
  30. package/dist/esm/components/Chains/AllChainsAvatar.js +7 -1
  31. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
  32. package/dist/esm/components/Chains/ChainList.js.map +1 -1
  33. package/dist/esm/components/Chains/ChainListItem.js.map +1 -1
  34. package/dist/esm/components/Chains/ChainsExpanded.js.map +1 -1
  35. package/dist/esm/components/Chains/PinChainButton.js.map +1 -1
  36. package/dist/esm/components/Chains/SelectChainExpansionContent.js.map +1 -1
  37. package/dist/esm/components/Chains/SelectChainPageContent.js.map +1 -1
  38. package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
  39. package/dist/esm/components/ContextMenu.js.map +1 -1
  40. package/dist/esm/components/ContractComponent/NFT/NFTBase.js.map +1 -1
  41. package/dist/esm/components/Dialog/Dialog.js +2 -1
  42. package/dist/esm/components/Dialog/Dialog.js.map +1 -1
  43. package/dist/esm/components/ExecutionStatusCard/ExecutionChecklist.js.map +1 -1
  44. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.js.map +1 -1
  45. package/dist/esm/components/ExecutionStatusCard/StaggeredRevealTypography.js.map +1 -1
  46. package/dist/esm/components/ExecutionStatusCard/StatusIcon.js.map +1 -1
  47. package/dist/esm/components/Expansion/Expansion.js +4 -3
  48. package/dist/esm/components/Expansion/Expansion.js.map +1 -1
  49. package/dist/esm/components/Expansion/ExpansionTransition.js.map +1 -1
  50. package/dist/esm/components/FeeBreakdownTooltip.js.map +1 -1
  51. package/dist/esm/components/Header/ActivitiesButton.js.map +1 -1
  52. package/dist/esm/components/Header/BackButton.js.map +1 -1
  53. package/dist/esm/components/Header/CloseDrawerButton.js.map +1 -1
  54. package/dist/esm/components/Header/DisconnectIconButton.js.map +1 -1
  55. package/dist/esm/components/Header/HeaderTabs.js.map +1 -1
  56. package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
  57. package/dist/esm/components/Header/SettingsButton.js +2 -1
  58. package/dist/esm/components/Header/SettingsButton.js.map +1 -1
  59. package/dist/esm/components/Header/WalletHeader.js.map +1 -1
  60. package/dist/esm/components/Header/WalletMenu.js.map +1 -1
  61. package/dist/esm/components/IconCircle/IconCircle.js +2 -1
  62. package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
  63. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -1
  64. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -1
  65. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -1
  66. package/dist/esm/components/Messages/AccountDeployedMessage.js.map +1 -1
  67. package/dist/esm/components/Messages/AccountNotDeployedMessage.js.map +1 -1
  68. package/dist/esm/components/Messages/AlertMessage.js.map +1 -1
  69. package/dist/esm/components/Messages/FundsSufficiencyMessage.js.map +1 -1
  70. package/dist/esm/components/Messages/GasRefuelMessage.js.map +1 -1
  71. package/dist/esm/components/Messages/GasSufficiencyMessage.js.map +1 -1
  72. package/dist/esm/components/Messages/MinFromAmountUSDMessage.js.map +1 -1
  73. package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.js.map +1 -1
  74. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js +27 -0
  75. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js.map +1 -0
  76. package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
  77. package/dist/esm/components/Messages/WarningMessages.js +2 -0
  78. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  79. package/dist/esm/components/Messages/useMessageQueue.js +6 -1
  80. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  81. package/dist/esm/components/NotFound.js.map +1 -1
  82. package/dist/esm/components/PoweredBy/PoweredBy.js.map +1 -1
  83. package/dist/esm/components/ProgressToNextUpdate.js.map +1 -1
  84. package/dist/esm/components/ReverseTokensButton/ReverseTokensButton.js.map +1 -1
  85. package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
  86. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  87. package/dist/esm/components/RouteCard/RouteCardSkeleton.js.map +1 -1
  88. package/dist/esm/components/RouteCard/RouteDetails.js +2 -1
  89. package/dist/esm/components/RouteCard/RouteDetails.js.map +1 -1
  90. package/dist/esm/components/RouteCard/RouteNotFoundCard.js.map +1 -1
  91. package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -1
  92. package/dist/esm/components/RouteCard/RouteToken.js.map +1 -1
  93. package/dist/esm/components/RouteCard/RouteTokens.js.map +1 -1
  94. package/dist/esm/components/Routes/LimitOrderRoutes.js +2 -2
  95. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -1
  96. package/dist/esm/components/Routes/Routes.js.map +1 -1
  97. package/dist/esm/components/Routes/RoutesContent.js +2 -2
  98. package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
  99. package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
  100. package/dist/esm/components/Search/SearchInput.js.map +1 -1
  101. package/dist/esm/components/SelectChainAndToken.js.map +1 -1
  102. package/dist/esm/components/SelectTokenButton/SelectTokenButton.js.map +1 -1
  103. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  104. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +2 -2
  105. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  106. package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -1
  107. package/dist/esm/components/Skeleton/WidgetSkeleton.js +2 -1
  108. package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
  109. package/dist/esm/components/Step/StepActions.js +18 -16
  110. package/dist/esm/components/Step/StepActions.js.map +1 -1
  111. package/dist/esm/components/StepActions/SentToWalletRow.js.map +1 -1
  112. package/dist/esm/components/StepActions/StepActionRow.js +2 -1
  113. package/dist/esm/components/StepActions/StepActionRow.js.map +1 -1
  114. package/dist/esm/components/StepActions/StepActionsList.js.map +1 -1
  115. package/dist/esm/components/SwapButton/SwapButton.js.map +1 -1
  116. package/dist/esm/components/Switch.js +1 -1
  117. package/dist/esm/components/Switch.js.map +1 -1
  118. package/dist/esm/components/Tabs/Tabs.style.js +4 -2
  119. package/dist/esm/components/Tabs/Tabs.style.js.map +1 -1
  120. package/dist/esm/components/TextFitter/TextFitter.js.map +1 -1
  121. package/dist/esm/components/Timer/StepStatusTimer.js.map +1 -1
  122. package/dist/esm/components/Token/Token.js.map +1 -1
  123. package/dist/esm/components/TokenList/PinTokenButton.js.map +1 -1
  124. package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
  125. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
  126. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  127. package/dist/esm/components/TokenList/TokenListItem.js +46 -8
  128. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  129. package/dist/esm/components/TokenList/VirtualizedTokenList.js +22 -9
  130. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  131. package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -1
  132. package/dist/esm/components/TokenRate/TokenRate.js +2 -1
  133. package/dist/esm/components/TokenRate/TokenRate.js.map +1 -1
  134. package/dist/esm/components/Tools/ToolItem.js.map +1 -1
  135. package/dist/esm/components/Tools/Tools.js.map +1 -1
  136. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +22 -21
  137. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
  138. package/dist/esm/components/TransactionCard/TransactionCard.js.map +1 -1
  139. package/dist/esm/components/TransactionCard/TransactionCardSkeleton.js.map +1 -1
  140. package/dist/esm/config/version.d.ts +1 -1
  141. package/dist/esm/config/version.js +1 -1
  142. package/dist/esm/config/version.js.map +1 -1
  143. package/dist/esm/hooks/timer/time.js +2 -2
  144. package/dist/esm/hooks/timer/time.js.map +1 -1
  145. package/dist/esm/hooks/useAccountsBalancesData.js +1 -14
  146. package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
  147. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  148. package/dist/esm/hooks/useAvailableChains.js +2 -1
  149. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  150. package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
  151. package/dist/esm/hooks/useExplorer.js +4 -0
  152. package/dist/esm/hooks/useExplorer.js.map +1 -1
  153. package/dist/esm/hooks/useFlaggedTokenGuard.js +28 -0
  154. package/dist/esm/hooks/useFlaggedTokenGuard.js.map +1 -0
  155. package/dist/esm/hooks/useGasSufficiency.js +3 -1
  156. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  157. package/dist/esm/hooks/useMaxSendAmount.js +15 -0
  158. package/dist/esm/hooks/useMaxSendAmount.js.map +1 -0
  159. package/dist/esm/hooks/usePacedRouteExecution.js +3 -2
  160. package/dist/esm/hooks/usePacedRouteExecution.js.map +1 -1
  161. package/dist/esm/hooks/useRouteExecutionMessage.js +3 -2
  162. package/dist/esm/hooks/useRouteExecutionMessage.js.map +1 -1
  163. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  164. package/dist/esm/hooks/useRoutes.js +3 -1
  165. package/dist/esm/hooks/useRoutes.js.map +1 -1
  166. package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
  167. package/dist/esm/hooks/useToAddressRequirements.d.ts +2 -0
  168. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  169. package/dist/esm/hooks/useToAddressRequirements.js +7 -1
  170. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  171. package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
  172. package/dist/esm/hooks/useTokenBalances.js +7 -2
  173. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  174. package/dist/esm/hooks/useTokenBalancesQueries.js +32 -29
  175. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
  176. package/dist/esm/hooks/useTokenSearch.js +3 -5
  177. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  178. package/dist/esm/hooks/useTokens.js +14 -10
  179. package/dist/esm/hooks/useTokens.js.map +1 -1
  180. package/dist/esm/hooks/useWideVariant.js +2 -1
  181. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  182. package/dist/esm/i18n/bn.json +3 -1
  183. package/dist/esm/i18n/de.json +3 -1
  184. package/dist/esm/i18n/en.json +12 -3
  185. package/dist/esm/i18n/es.json +3 -1
  186. package/dist/esm/i18n/fr.json +3 -1
  187. package/dist/esm/i18n/hi.json +3 -1
  188. package/dist/esm/i18n/id.json +3 -1
  189. package/dist/esm/i18n/it.json +3 -1
  190. package/dist/esm/i18n/ja.json +3 -1
  191. package/dist/esm/i18n/ko.json +3 -1
  192. package/dist/esm/i18n/pl.json +3 -1
  193. package/dist/esm/i18n/pt.json +3 -1
  194. package/dist/esm/i18n/th.json +3 -1
  195. package/dist/esm/i18n/tr.json +3 -1
  196. package/dist/esm/i18n/uk.json +3 -1
  197. package/dist/esm/i18n/vi.json +3 -1
  198. package/dist/esm/i18n/zh.json +3 -1
  199. package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js.map +1 -1
  200. package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js.map +1 -1
  201. package/dist/esm/pages/LanguagesPage.js.map +1 -1
  202. package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -1
  203. package/dist/esm/pages/MainPage/MainPage.js +2 -1
  204. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  205. package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -1
  206. package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
  207. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  208. package/dist/esm/pages/RoutePriorityPage.js.map +1 -1
  209. package/dist/esm/pages/RoutesPage/RoutesPage.js +2 -2
  210. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  211. package/dist/esm/pages/SelectChainPage/SelectChainPage.js +13 -12
  212. package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  213. package/dist/esm/pages/SelectEnabledToolsPage.js +8 -5
  214. package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
  215. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +2 -1
  216. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  217. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
  218. package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  219. package/dist/esm/pages/SendToWallet/ConfirmAddressSheet.js.map +1 -1
  220. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  221. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  222. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  223. package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  224. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
  225. package/dist/esm/pages/SettingsPage/GasPriceSettings.js.map +1 -1
  226. package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
  227. package/dist/esm/pages/SettingsPage/ResetSettingsButton.js.map +1 -1
  228. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
  229. package/dist/esm/pages/SettingsPage/SettingsCard/BadgedValue.js.map +1 -1
  230. package/dist/esm/pages/SettingsPage/SettingsCard/SettingCardExpandable.js.map +1 -1
  231. package/dist/esm/pages/SettingsPage/SettingsPage.js.map +1 -1
  232. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -1
  233. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
  234. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js +2 -1
  235. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
  236. package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  237. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js +2 -1
  238. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
  239. package/dist/esm/pages/TransactionDetailsPage/ReceiptsCard.js.map +1 -1
  240. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +2 -1
  241. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  242. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsSkeleton.js.map +1 -1
  243. package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -1
  244. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js.map +1 -1
  245. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
  246. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.js.map +1 -1
  247. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +4 -3
  248. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  249. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  250. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +64 -0
  251. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -0
  252. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.js.map +1 -1
  253. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js +19 -16
  254. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js.map +1 -1
  255. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +3 -1
  256. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
  257. package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  258. package/dist/esm/pages/TransactionPage/TransactionReview.js +24 -2
  259. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  260. package/dist/esm/providers/I18nProvider/I18nProvider.js +37 -36
  261. package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  262. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  263. package/dist/esm/providers/ThemeProvider/ThemeProvider.js +2 -1
  264. package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
  265. package/dist/esm/providers/WalletProvider/WalletProvider.js +10 -9
  266. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  267. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
  268. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
  269. package/dist/esm/stores/StoreProvider.js.map +1 -1
  270. package/dist/esm/stores/form/FormStore.js.map +1 -1
  271. package/dist/esm/stores/form/FormUpdater.js.map +1 -1
  272. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
  273. package/dist/esm/stores/routes/useRouteExecutionIndicator.js +4 -3
  274. package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
  275. package/dist/esm/types/token.d.ts +4 -1
  276. package/dist/esm/types/token.d.ts.map +1 -1
  277. package/dist/esm/utils/compactNumberFormatter.js +1 -3
  278. package/dist/esm/utils/compactNumberFormatter.js.map +1 -1
  279. package/dist/esm/utils/customReceiver.js +7 -0
  280. package/dist/esm/utils/customReceiver.js.map +1 -0
  281. package/dist/esm/utils/gas.js +24 -0
  282. package/dist/esm/utils/gas.js.map +1 -0
  283. package/dist/esm/utils/getErrorMessage.js +0 -1
  284. package/dist/esm/utils/getErrorMessage.js.map +1 -1
  285. package/dist/esm/utils/limitOrder.js +1 -1
  286. package/dist/esm/utils/limitOrder.js.map +1 -1
  287. package/dist/esm/utils/token.js +21 -4
  288. package/dist/esm/utils/token.js.map +1 -1
  289. package/dist/esm/utils/tokenList.js +37 -23
  290. package/dist/esm/utils/tokenList.js.map +1 -1
  291. package/package.json +15 -15
  292. package/src/components/AmountInput/AmountInputEndAdornment.tsx +2 -21
  293. package/src/components/AmountInputCard/PercentageChips.tsx +2 -18
  294. package/src/components/Chains/AllChainsAvatar.tsx +7 -1
  295. package/src/components/Messages/UnsupportedToAddressMessage.tsx +24 -0
  296. package/src/components/Messages/WarningMessages.tsx +3 -0
  297. package/src/components/Messages/useMessageQueue.ts +9 -0
  298. package/src/components/Routes/LimitOrderRoutes.tsx +5 -2
  299. package/src/components/Routes/RoutesContent.tsx +5 -2
  300. package/src/components/SendToWallet/SendToWalletExpandButton.tsx +2 -1
  301. package/src/components/TokenList/TokenListItem.tsx +68 -9
  302. package/src/components/TokenList/VirtualizedTokenList.tsx +33 -9
  303. package/src/components/TokenList/types.ts +4 -0
  304. package/src/config/version.ts +1 -1
  305. package/src/hooks/useAccountsBalancesData.ts +4 -31
  306. package/src/hooks/useAvailableChains.ts +1 -0
  307. package/src/hooks/useExplorer.ts +2 -0
  308. package/src/hooks/useFlaggedTokenGuard.ts +33 -0
  309. package/src/hooks/useGasSufficiency.ts +9 -1
  310. package/src/hooks/useMaxSendAmount.ts +21 -0
  311. package/src/hooks/useRoutes.ts +7 -0
  312. package/src/hooks/useToAddressRequirements.ts +17 -1
  313. package/src/hooks/useTokenBalances.ts +18 -2
  314. package/src/hooks/useTokenBalancesQueries.ts +12 -4
  315. package/src/hooks/useTokenSearch.ts +1 -5
  316. package/src/hooks/useTokens.ts +28 -13
  317. package/src/pages/MainPage/ReviewButton.tsx +6 -2
  318. package/src/pages/RoutesPage/RoutesPage.tsx +5 -2
  319. package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +93 -0
  320. package/src/pages/TransactionPage/TransactionReview.tsx +28 -1
  321. package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
  322. package/src/types/token.ts +6 -3
  323. package/src/utils/customReceiver.ts +7 -0
  324. package/src/utils/gas.ts +41 -0
  325. package/src/utils/token.ts +53 -9
  326. package/src/utils/tokenList.ts +27 -7
  327. package/dist/esm/hooks/useFilteredByTokenBalances.js +0 -74
  328. package/dist/esm/hooks/useFilteredByTokenBalances.js.map +0 -1
  329. package/src/hooks/useFilteredByTokenBalances.ts +0 -145
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/index.js",
@@ -52,22 +52,22 @@
52
52
  "dependencies": {
53
53
  "@emotion/react": "^11.14.0",
54
54
  "@emotion/styled": "^11.14.1",
55
- "@lifi/sdk": "^4.1.0",
56
- "@mui/icons-material": "^9.2.0",
57
- "@mui/material": "^9.2.0",
58
- "@mui/system": "^9.2.0",
59
- "@tanstack/react-router": "^1.170.17",
60
- "@tanstack/react-virtual": "^3.14.5",
55
+ "@lifi/sdk": "^4.6.1",
56
+ "@lifi/wallet-management": "4.2.0",
57
+ "@lifi/widget-provider": "4.4.0",
58
+ "@mui/icons-material": "^9.4.0",
59
+ "@mui/material": "^9.4.0",
60
+ "@mui/system": "^9.4.0",
61
+ "@tanstack/react-router": "^1.170.32",
62
+ "@tanstack/react-virtual": "^3.14.10",
61
63
  "eventemitter3": "^5.0.4",
62
- "i18next": "^26.3.6",
63
- "microdiff": "^1.5.0",
64
- "motion": "^12.42.2",
65
- "react-i18next": "^17.0.9",
66
- "react-intersection-observer": "^10.1.0",
64
+ "i18next": "^26.4.1",
65
+ "microdiff": "^1.6.0",
66
+ "motion": "^13.2.0",
67
+ "react-i18next": "^17.0.13",
68
+ "react-intersection-observer": "^11.0.1",
67
69
  "react-transition-group": "^4.4.5",
68
- "zustand": "^5.0.14",
69
- "@lifi/wallet-management": "4.1.2",
70
- "@lifi/widget-provider": "4.3.0"
70
+ "zustand": "^5.0.15"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "@tanstack/react-query": ">=5.90.0",
@@ -4,7 +4,7 @@ import type React from 'react'
4
4
  import { type JSX, memo } from 'react'
5
5
  import { useTranslation } from 'react-i18next'
6
6
  import { useAvailableChains } from '../../hooks/useAvailableChains.js'
7
- import { useGasRecommendation } from '../../hooks/useGasRecommendation.js'
7
+ import { useMaxSendAmount } from '../../hooks/useMaxSendAmount.js'
8
8
  import { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'
9
9
  import type { FormTypeProps } from '../../stores/form/types.js'
10
10
  import { FormKeyHelper } from '../../stores/form/types.js'
@@ -29,28 +29,10 @@ export const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps>
29
29
  const chain = getChainById(chainId)
30
30
  const { account } = useAccount({ chainType: chain?.chainType })
31
31
 
32
- // We get gas recommendations for the source chain to make sure that after pressing the Max button
33
- // the user will have enough funds remaining to cover gas costs
34
- const { data } = useGasRecommendation(chainId)
35
-
36
32
  const { token } = useTokenAddressBalance(chainId, tokenAddress)
37
-
38
- const getMaxAmount = () => {
39
- if (!token?.amount) {
40
- return 0n
41
- }
42
- let maxAmount = token.amount
43
- if (chain?.nativeToken.address === tokenAddress && data?.recommended) {
44
- const recommendedAmount = BigInt(data.recommended.amount)
45
- if (token.amount > recommendedAmount) {
46
- maxAmount = token.amount - recommendedAmount
47
- }
48
- }
49
- return maxAmount
50
- }
33
+ const maxAmount = useMaxSendAmount(chainId, tokenAddress)
51
34
 
52
35
  const handlePercentage = (percentage: number) => {
53
- const maxAmount = getMaxAmount()
54
36
  if (maxAmount && token?.decimals) {
55
37
  const percentageAmount = (maxAmount * BigInt(percentage)) / 100n
56
38
  setFieldValue(
@@ -64,7 +46,6 @@ export const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps>
64
46
  }
65
47
 
66
48
  const handleMax = () => {
67
- const maxAmount = getMaxAmount()
68
49
  if (maxAmount && token?.decimals) {
69
50
  setFieldValue(
70
51
  FormKeyHelper.getAmountKey(formType),
@@ -3,8 +3,8 @@ import { useAccount } from '@lifi/wallet-management'
3
3
  import { type JSX, memo } from 'react'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import { useAvailableChains } from '../../hooks/useAvailableChains.js'
6
- import { useGasRecommendation } from '../../hooks/useGasRecommendation.js'
7
6
  import { useLinkedLimitFields } from '../../hooks/useLinkedLimitFields.js'
7
+ import { useMaxSendAmount } from '../../hooks/useMaxSendAmount.js'
8
8
  import { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'
9
9
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
10
10
  import type { FormTypeProps } from '../../stores/form/types.js'
@@ -33,22 +33,8 @@ export const PercentageChips: React.NamedExoticComponent<FormTypeProps> = memo(
33
33
  const chain = getChainById(chainId)
34
34
  const { account } = useAccount({ chainType: chain?.chainType })
35
35
 
36
- const { data } = useGasRecommendation(chainId)
37
36
  const { token } = useTokenAddressBalance(chainId, tokenAddress)
38
-
39
- const getMaxAmount = (): bigint => {
40
- if (!token?.amount) {
41
- return 0n
42
- }
43
- let maxAmount = token.amount
44
- if (chain?.nativeToken.address === tokenAddress && data?.recommended) {
45
- const recommendedAmount = BigInt(data.recommended.amount)
46
- if (token.amount > recommendedAmount) {
47
- maxAmount = token.amount - recommendedAmount
48
- }
49
- }
50
- return maxAmount
51
- }
37
+ const maxAmount = useMaxSendAmount(chainId, tokenAddress)
52
38
 
53
39
  // In limit mode the send amount must flow through the linked-field
54
40
  // derivation so the receive amount recomputes; otherwise it is a plain
@@ -62,7 +48,6 @@ export const PercentageChips: React.NamedExoticComponent<FormTypeProps> = memo(
62
48
  }
63
49
 
64
50
  const handlePercentage = (percentage: number): void => {
65
- const maxAmount = getMaxAmount()
66
51
  if (maxAmount && token?.decimals) {
67
52
  const percentageAmount = (maxAmount * BigInt(percentage)) / 100n
68
53
  applyAmount(formatUnits(percentageAmount, token.decimals))
@@ -70,7 +55,6 @@ export const PercentageChips: React.NamedExoticComponent<FormTypeProps> = memo(
70
55
  }
71
56
 
72
57
  const handleMax = (): void => {
73
- const maxAmount = getMaxAmount()
74
58
  if (maxAmount && token?.decimals) {
75
59
  applyAmount(formatUnits(maxAmount, token.decimals))
76
60
  }
@@ -44,6 +44,12 @@ const chainTypeIcons = [
44
44
  icon: 'https://lifinance.github.io/types/src/assets/icons/chains/tron.svg',
45
45
  defaultChainId: ChainId.TRN,
46
46
  },
47
+ {
48
+ name: 'Stellar',
49
+ chainType: ChainType.STL,
50
+ icon: 'https://lifinance.github.io/types/src/assets/icons/chains/stellar.svg',
51
+ defaultChainId: ChainId.XLM,
52
+ },
47
53
  ]
48
54
 
49
55
  const maxChainAvatarsCount = 4
@@ -93,7 +99,7 @@ export const AllChainsAvatar: React.NamedExoticComponent<AllChainsAvatarProps> =
93
99
  }
94
100
  )
95
101
 
96
- if (existingChainTypeIcons.length === maxChainAvatarsCount) {
102
+ if (existingChainTypeIcons.length >= maxChainAvatarsCount) {
97
103
  return existingChainTypeIcons
98
104
  }
99
105
 
@@ -0,0 +1,24 @@
1
+ import WarningRounded from '@mui/icons-material/WarningRounded'
2
+ import type { BoxProps } from '@mui/material'
3
+ import { Typography } from '@mui/material'
4
+ import { useTranslation } from 'react-i18next'
5
+ import { AlertMessage } from './AlertMessage.js'
6
+
7
+ export const UnsupportedToAddressMessage: React.FC<BoxProps> = ({
8
+ ...props
9
+ }) => {
10
+ const { t } = useTranslation()
11
+ return (
12
+ <AlertMessage
13
+ title={
14
+ <Typography variant="body2" sx={{ px: 1, color: 'text.primary' }}>
15
+ {t('info.message.unsupportedToAddressMessage')}
16
+ </Typography>
17
+ }
18
+ icon={<WarningRounded />}
19
+ severity="warning"
20
+ multiline
21
+ {...props}
22
+ />
23
+ )
24
+ }
@@ -7,6 +7,7 @@ import { FundsSufficiencyMessage } from './FundsSufficiencyMessage.js'
7
7
  import { GasSufficiencyMessage } from './GasSufficiencyMessage.js'
8
8
  import { MinFromAmountUSDMessage } from './MinFromAmountUSDMessage.js'
9
9
  import { MissingRouteRequiredAccountMessage } from './MissingRouteRequiredAccountMessage.js'
10
+ import { UnsupportedToAddressMessage } from './UnsupportedToAddressMessage.js'
10
11
  import { useMessageQueue } from './useMessageQueue.js'
11
12
 
12
13
  type WarningMessagesProps = BoxProps & {
@@ -51,6 +52,8 @@ export const WarningMessages: React.FC<WarningMessagesProps> = ({
51
52
  return <AccountNotDeployedMessage {...props} />
52
53
  case 'ACCOUNT_DEPLOYED':
53
54
  return <AccountDeployedMessage {...props} />
55
+ case 'UNSUPPORTED_TO_ADDRESS':
56
+ return <UnsupportedToAddressMessage {...props} />
54
57
  default:
55
58
  return null
56
59
  }
@@ -22,6 +22,7 @@ export const useMessageQueue = (
22
22
  } => {
23
23
  const {
24
24
  requiredToAddress,
25
+ unsupportedReceiverBlocking,
25
26
  accountNotDeployedAtDestination,
26
27
  accountDeployedAtDestination,
27
28
  isLoading: isToAddressRequirementsLoading,
@@ -37,6 +38,13 @@ export const useMessageQueue = (
37
38
  const messageQueue = useMemo(() => {
38
39
  const queue: QueuedMessage[] = []
39
40
 
41
+ if (unsupportedReceiverBlocking) {
42
+ queue.push({
43
+ id: 'UNSUPPORTED_TO_ADDRESS',
44
+ priority: 7,
45
+ })
46
+ }
47
+
40
48
  if (missingChain) {
41
49
  queue.push({
42
50
  id: 'MISSING_ROUTE_REQUIRED_ACCOUNT',
@@ -94,6 +102,7 @@ export const useMessageQueue = (
94
102
  accountDeployedAtDestination,
95
103
  accountNotDeployedAtDestination,
96
104
  requiredToAddress,
105
+ unsupportedReceiverBlocking,
97
106
  missingChain,
98
107
  missingAccountAddress,
99
108
  belowMinFromAmountUSD,
@@ -17,7 +17,8 @@ export const LimitOrderRoutes: React.FC<CardProps> = (props) => {
17
17
  'selectedRouteId'
18
18
  )
19
19
  const { setFieldValue } = useFieldActions()
20
- const { requiredToAddress } = useToAddressRequirements()
20
+ const { requiredToAddress, unsupportedReceiverBlocking } =
21
+ useToAddressRequirements()
21
22
 
22
23
  const currentRoute = routes?.[0]
23
24
 
@@ -25,7 +26,9 @@ export const LimitOrderRoutes: React.FC<CardProps> = (props) => {
25
26
  return null
26
27
  }
27
28
 
28
- const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress
29
+ const toAddressUnsatisfied =
30
+ currentRoute &&
31
+ (unsupportedReceiverBlocking || (requiredToAddress && !toAddress))
29
32
  const allowInteraction = !toAddressUnsatisfied
30
33
 
31
34
  const activeRouteId =
@@ -43,12 +43,15 @@ export const RoutesContent: React.NamedExoticComponent<RoutesContentProps> =
43
43
 
44
44
  const { account } = useAccount({ chainType: fromChain?.chainType })
45
45
  const [toAddress] = useFieldValues('toAddress')
46
- const { requiredToAddress } = useToAddressRequirements()
46
+ const { requiredToAddress, unsupportedReceiverBlocking } =
47
+ useToAddressRequirements()
47
48
 
48
49
  const currentRoute = routes?.[0]
49
50
 
50
51
  const routeNotFound = !currentRoute && !isLoading && !isFetching
51
- const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress
52
+ const toAddressUnsatisfied =
53
+ currentRoute &&
54
+ (unsupportedReceiverBlocking || (requiredToAddress && !toAddress))
52
55
  const allowInteraction = account.isConnected && !toAddressUnsatisfied
53
56
 
54
57
  const title =
@@ -16,12 +16,13 @@ export const SendToWalletExpandButton = (): JSX.Element => {
16
16
  const { toAddresses, disabledUI, hiddenUI } = useWidgetConfig()
17
17
  const hiddenToAddress = hiddenUI?.toAddress
18
18
  const disabledToAddress = disabledUI?.toAddress
19
- const { requiredToAddress } = useToAddressRequirements()
19
+ const { requiredToAddress, unsupportedToAddress } = useToAddressRequirements()
20
20
  const [toAddressValue] = useFieldValues('toAddress')
21
21
 
22
22
  const visible =
23
23
  !hiddenToAddress &&
24
24
  !disabledToAddress &&
25
+ !unsupportedToAddress &&
25
26
  !toAddressValue &&
26
27
  !requiredToAddress
27
28
 
@@ -1,7 +1,8 @@
1
1
  import type { StaticToken } from '@lifi/sdk'
2
2
  import { ChainType } from '@lifi/sdk'
3
3
  import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'
4
- import WarningRounded from '@mui/icons-material/WarningRounded'
4
+ import ReportRoundedIcon from '@mui/icons-material/ReportRounded'
5
+ import VerifiedIcon from '@mui/icons-material/Verified'
5
6
  import {
6
7
  Avatar,
7
8
  Box,
@@ -18,6 +19,7 @@ import { memo, useMemo, useRef, useState } from 'react'
18
19
  import { useTranslation } from 'react-i18next'
19
20
  import { useLongPress } from '../../hooks/useLongPress.js'
20
21
  import { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'
22
+ import { getTokenVerificationProvider } from '../../utils/token.js'
21
23
  import { shortenAddress } from '../../utils/wallet.js'
22
24
  import { TokenAvatar } from '../Avatar/TokenAvatar.js'
23
25
  import { ListItemButton } from '../ListItem/ListItemButton.js'
@@ -36,6 +38,7 @@ export const TokenListItem: React.FC<TokenListItemProps> = memo(
36
38
  start,
37
39
  token,
38
40
  chain,
41
+ chainName,
39
42
  isBalanceLoading,
40
43
  startAdornment,
41
44
  endAdornment,
@@ -56,6 +59,7 @@ export const TokenListItem: React.FC<TokenListItemProps> = memo(
56
59
  isBalanceLoading={isBalanceLoading}
57
60
  onClick={onClick}
58
61
  chain={chain}
62
+ chainName={chainName}
59
63
  selected={selected}
60
64
  onShowTokenDetails={onShowTokenDetails}
61
65
  />
@@ -121,6 +125,7 @@ const TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(
121
125
  onClick,
122
126
  token,
123
127
  chain,
128
+ chainName,
124
129
  isBalanceLoading,
125
130
  selected,
126
131
  onShowTokenDetails,
@@ -166,6 +171,64 @@ const TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(
166
171
  onShowTokenDetails(token.address, withoutContractAddress, token.chainId)
167
172
  )
168
173
 
174
+ // The native token is badged ahead of any verdict: the provider screens
175
+ // the native-address convention and calls it a scam on some chains.
176
+ // A token the main list or the integrator vouches for needs no warning;
177
+ // anything else without a clean verdict keeps the amber one.
178
+ let verificationBadge:
179
+ | { Icon: typeof VerifiedIcon; color: string; title: string }
180
+ | undefined
181
+ if (token.native) {
182
+ verificationBadge = {
183
+ Icon: VerifiedIcon,
184
+ color: 'info.main',
185
+ title: chainName
186
+ ? t('tooltip.tokenNativeOnChain', {
187
+ tokenSymbol: token.symbol,
188
+ chainName,
189
+ })
190
+ : t('tooltip.tokenNative', { tokenSymbol: token.symbol }),
191
+ }
192
+ } else if (token.verificationStatus === 'flagged') {
193
+ verificationBadge = {
194
+ Icon: ReportRoundedIcon,
195
+ color: 'error.main',
196
+ title: t('warning.message.tokenFlagged', {
197
+ tokenSymbol: token.symbol,
198
+ }),
199
+ }
200
+ } else if (token.verificationStatus === 'verified') {
201
+ const provider = getTokenVerificationProvider(token)
202
+ verificationBadge = {
203
+ Icon: VerifiedIcon,
204
+ color: 'success.main',
205
+ title: provider
206
+ ? t('tooltip.tokenVerifiedByProvider', {
207
+ tokenSymbol: token.symbol,
208
+ provider,
209
+ })
210
+ : t('tooltip.tokenVerified', { tokenSymbol: token.symbol }),
211
+ }
212
+ } else if (
213
+ token.verificationStatus === 'unverified' &&
214
+ !token.listed &&
215
+ !token.verified
216
+ ) {
217
+ verificationBadge = {
218
+ Icon: ReportRoundedIcon,
219
+ color: 'warning.main',
220
+ title: t('warning.message.tokenUnverifiedByProvider', {
221
+ tokenSymbol: token.symbol,
222
+ }),
223
+ }
224
+ } else if (!token.verificationStatus && !token.listed && !token.verified) {
225
+ verificationBadge = {
226
+ Icon: ReportRoundedIcon,
227
+ color: 'warning.main',
228
+ title: t('warning.message.tokenUnverified'),
229
+ }
230
+ }
231
+
169
232
  return (
170
233
  <ListItemButton
171
234
  onClick={handleClick}
@@ -195,17 +258,13 @@ const TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(
195
258
  primary={
196
259
  <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
197
260
  {token.symbol}
198
- {!token.verified && (
199
- <Tooltip
200
- title={t('warning.message.unverifiedToken')}
201
- placement="top"
202
- arrow
203
- >
204
- <WarningRounded
261
+ {verificationBadge && (
262
+ <Tooltip title={verificationBadge.title} placement="top" arrow>
263
+ <verificationBadge.Icon
205
264
  sx={{
206
265
  display: 'flex',
207
266
  fontSize: 16,
208
- color: 'warning.main',
267
+ color: verificationBadge.color,
209
268
  cursor: 'help',
210
269
  }}
211
270
  />
@@ -60,6 +60,24 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
60
60
  [tokens]
61
61
  )
62
62
 
63
+ // The hoisted native token sits above every category, so the row after it
64
+ // opens the first one. Only a row the hoist could have moved counts.
65
+ const nativeTokenHoisted = useMemo(() => {
66
+ const first = tokens[0]
67
+ return (
68
+ !!first?.native &&
69
+ !first.pinned &&
70
+ !first.featured &&
71
+ !first.popular &&
72
+ !first.verified
73
+ )
74
+ }, [tokens])
75
+
76
+ const isListStartIndex = useCallback(
77
+ (index: number) => index === 0 || (index === 1 && nativeTokenHoisted),
78
+ [nativeTokenHoisted]
79
+ )
80
+
63
81
  const estimateSize = useCallback(
64
82
  (index: number) => {
65
83
  const currentToken = tokens[index]
@@ -67,7 +85,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
67
85
  let size = tokenItemHeight
68
86
 
69
87
  // Pinned tokens (always shown, even in all networks mode)
70
- if (currentToken.pinned && index === 0) {
88
+ if (currentToken.pinned && isListStartIndex(index)) {
71
89
  size += 24
72
90
  }
73
91
  if (previousToken?.pinned && !currentToken.pinned) {
@@ -78,13 +96,19 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
78
96
  return size
79
97
  }
80
98
 
81
- if (currentToken.featured && !currentToken.pinned && index === 0) {
99
+ if (
100
+ currentToken.featured &&
101
+ !currentToken.pinned &&
102
+ isListStartIndex(index)
103
+ ) {
82
104
  size += 24
83
105
  }
84
106
 
85
- // Category transition (excluding pinned tokens)
107
+ // Category transition (excluding pinned tokens). The hoisted native row
108
+ // sits above every band, so the row after it ends nothing.
86
109
  const isNotPinned = !currentToken.pinned && !previousToken?.pinned
87
110
  if (
111
+ !isListStartIndex(index) &&
88
112
  isNotPinned &&
89
113
  ((previousToken?.amount && !currentToken.amount) ||
90
114
  (previousToken?.featured && !currentToken.featured) ||
@@ -95,7 +119,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
95
119
 
96
120
  return size
97
121
  },
98
- [tokens, showCategories]
122
+ [tokens, showCategories, isListStartIndex]
99
123
  )
100
124
 
101
125
  const virtualizerConfig = useMemo(
@@ -142,8 +166,9 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
142
166
  const previousToken: TokenAmount | undefined = tokens[item.index - 1]
143
167
  const chain = chainsSet?.get(currentToken.chainId)
144
168
 
169
+ const isListStart = isListStartIndex(item.index)
145
170
  const isNotPinned = !currentToken.pinned
146
- const isFirstPinnedToken = currentToken.pinned && item.index === 0
171
+ const isFirstPinnedToken = currentToken.pinned && isListStart
147
172
  const isTransitionFromPinned = previousToken?.pinned && isNotPinned
148
173
 
149
174
  // Category transitions (excluding pinned)
@@ -168,7 +193,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
168
193
 
169
194
  if (
170
195
  (isTransitionFromPinned && currentToken.featured) ||
171
- (currentToken.featured && isNotPinned && item.index === 0)
196
+ (currentToken.featured && isNotPinned && isListStart)
172
197
  ) {
173
198
  return t('main.featuredTokens')
174
199
  }
@@ -211,6 +236,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
211
236
  start={item.start}
212
237
  token={currentToken}
213
238
  chain={isAllNetworks ? chain : undefined}
239
+ chainName={chain?.name}
214
240
  selected={isSelected}
215
241
  onShowTokenDetails={onShowTokenDetails}
216
242
  isBalanceLoading={isBalanceLoading}
@@ -224,9 +250,7 @@ export const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({
224
250
  px: 1.5,
225
251
  pt:
226
252
  isFirstPinnedToken ||
227
- (currentToken.featured &&
228
- isNotPinned &&
229
- item.index === 0)
253
+ (currentToken.featured && isNotPinned && isListStart)
230
254
  ? 0
231
255
  : 1,
232
256
  pb: 1,
@@ -35,6 +35,8 @@ export interface TokenListItemProps extends TokenListItemBaseProps {
35
35
  chainId: number
36
36
  ) => void
37
37
  chain?: ExtendedChain
38
+ /** Resolved for every row, unlike `chain`, which the list passes only in all-networks mode. */
39
+ chainName?: string
38
40
  isBalanceLoading?: boolean
39
41
  startAdornment?: React.ReactNode
40
42
  endAdornment?: React.ReactNode
@@ -50,6 +52,8 @@ export interface TokenListItemButtonProps {
50
52
  onClick?(tokenAddress: string, chainId?: number): void
51
53
  token: TokenAmount
52
54
  chain?: ExtendedChain
55
+ /** Resolved for every row, unlike `chain`, which the list passes only in all-networks mode. */
56
+ chainName?: string
53
57
  isBalanceLoading?: boolean
54
58
  selected?: boolean
55
59
  }
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget'
2
- export const version = '4.4.0'
2
+ export const version = '4.6.0'
@@ -1,9 +1,8 @@
1
- import type { ChainType, TokenExtended } from '@lifi/sdk'
1
+ import type { TokenExtended } from '@lifi/sdk'
2
2
  import { useAccount } from '@lifi/wallet-management'
3
3
  import { useMemo } from 'react'
4
4
  import type { FormType } from '../stores/form/types.js'
5
5
  import { useChains } from './useChains.js'
6
- import { useFilteredTokensByBalance } from './useFilteredByTokenBalances.js'
7
6
 
8
7
  export const useAccountsBalancesData = (
9
8
  selectedChainId?: number,
@@ -14,25 +13,6 @@ export const useAccountsBalancesData = (
14
13
  data: Record<string, Record<number, TokenExtended[]>> | undefined
15
14
  isLoading: boolean
16
15
  } => {
17
- const { data: accountsWithTokens, isLoading: isAccountsLoading } =
18
- useAccountsData(selectedChainId, formType, isAllNetworks, allTokens)
19
-
20
- // Filter out EVM tokens that do not have balances
21
- const { data: filteredTokens, isLoading: isCachedBalancesLoading } =
22
- useFilteredTokensByBalance(accountsWithTokens, formType)
23
-
24
- return {
25
- data: filteredTokens,
26
- isLoading: isAccountsLoading || isCachedBalancesLoading,
27
- }
28
- }
29
-
30
- const useAccountsData = (
31
- selectedChainId?: number,
32
- formType?: FormType,
33
- isAllNetworks?: boolean,
34
- allTokens?: Record<number, TokenExtended[]>
35
- ) => {
36
16
  const {
37
17
  chains: allChains,
38
18
  isLoading: isChainsLoading,
@@ -72,7 +52,7 @@ const useAccountsData = (
72
52
  )
73
53
  if (accountChains) {
74
54
  const chainIdSet = new Set(accountChains.map((chain) => chain.id))
75
- const filteredTokens = Object.entries(allTokens).reduce(
55
+ acc[account.address] = Object.entries(allTokens).reduce(
76
56
  (tokenAcc, [chainIdStr, tokens]) => {
77
57
  const chainId = Number(chainIdStr)
78
58
  if (chainIdSet.has(chainId)) {
@@ -80,20 +60,13 @@ const useAccountsData = (
80
60
  }
81
61
  return tokenAcc
82
62
  },
83
- {} as { [chainId: number]: TokenExtended[] }
63
+ {} as Record<number, TokenExtended[]>
84
64
  )
85
- acc[account.address] = {
86
- chainType: account.chainType,
87
- tokens: filteredTokens,
88
- }
89
65
  }
90
66
  }
91
67
  return acc
92
68
  },
93
- {} as Record<
94
- string,
95
- { chainType: ChainType; tokens: Record<number, TokenExtended[]> }
96
- >
69
+ {} as Record<string, Record<number, TokenExtended[]>>
97
70
  )
98
71
  }, [accounts, chains, allTokens])
99
72
 
@@ -19,6 +19,7 @@ const supportedChainTypes = [
19
19
  ChainType.UTXO,
20
20
  ChainType.MVM,
21
21
  ChainType.TVM,
22
+ ChainType.STL,
22
23
  ]
23
24
 
24
25
  export const useAvailableChains = (
@@ -13,6 +13,8 @@ const explorerPathOverrides: Partial<
13
13
  [ChainId.SUI]: { txPath: 'txblock', addressPath: 'coin' },
14
14
  [ChainId.LTR]: { txPath: 'logs', addressPath: 'accounts' },
15
15
  [ChainType.TVM]: { txPath: '#/transaction', addressPath: '#/address' },
16
+ // StellarExpert and steexp both route accounts at /account, never /address.
17
+ [ChainType.STL]: { txPath: 'tx', addressPath: 'account' },
16
18
  }
17
19
 
18
20
  type TransactionLinkProps = {
@@ -0,0 +1,33 @@
1
+ import type { RouteExtended, Token } from '@lifi/sdk'
2
+ import type { RefObject } from 'react'
3
+ import { useMemo, useRef } from 'react'
4
+ import type { BottomSheetBase } from '../components/BottomSheet/types.js'
5
+ import { getNativeTokenAddresses } from '../utils/token.js'
6
+ import { useAvailableChains } from './useAvailableChains.js'
7
+
8
+ /**
9
+ * Route tokens the screening provider flagged, and the sheet that warns about
10
+ * them before the transaction starts. A native token is exempt: the provider
11
+ * screens the native-address convention and calls it a scam on some chains.
12
+ */
13
+ export const useFlaggedTokenGuard = (
14
+ route: RouteExtended
15
+ ): {
16
+ flaggedTokens: Token[]
17
+ flaggedTokenSheetRef: RefObject<BottomSheetBase | null>
18
+ } => {
19
+ const { chains } = useAvailableChains()
20
+ const flaggedTokenSheetRef = useRef<BottomSheetBase>(null)
21
+
22
+ const flaggedTokens = useMemo(() => {
23
+ const nativeTokenAddresses = getNativeTokenAddresses(chains)
24
+ return [route.fromToken, route.toToken].filter(
25
+ (token) =>
26
+ token.verificationStatus === 'flagged' &&
27
+ nativeTokenAddresses.get(token.chainId)?.toLowerCase() !==
28
+ token.address.toLowerCase()
29
+ )
30
+ }, [chains, route.fromToken, route.toToken])
31
+
32
+ return { flaggedTokens, flaggedTokenSheetRef }
33
+ }