@lifi/widget 4.5.0 → 4.7.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 (522) hide show
  1. package/README.md +26 -3
  2. package/dist/esm/App.d.ts +1 -2
  3. package/dist/esm/App.d.ts.map +1 -1
  4. package/dist/esm/AppDrawer.d.ts +1 -2
  5. package/dist/esm/AppDrawer.d.ts.map +1 -1
  6. package/dist/esm/AppDrawer.js +2 -1
  7. package/dist/esm/AppDrawer.js.map +1 -1
  8. package/dist/esm/components/ActionRow/ActionRow.d.ts +1 -2
  9. package/dist/esm/components/ActionRow/ActionRow.d.ts.map +1 -1
  10. package/dist/esm/components/AmountInput/AmountInput.js +13 -7
  11. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  12. package/dist/esm/components/AmountInput/AmountInput.style.d.ts +2 -2
  13. package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
  14. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts +1 -2
  15. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts.map +1 -1
  16. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +2 -13
  17. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  18. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts +1 -2
  19. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts.map +1 -1
  20. package/dist/esm/components/AmountInputCard/PercentageChips.js +2 -13
  21. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -1
  22. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +1 -1
  23. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -1
  24. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +6 -2
  25. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
  26. package/dist/esm/components/AmountInputCard/SendAmountCard.js +13 -6
  27. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -1
  28. package/dist/esm/components/Avatar/Avatar.d.ts +1 -2
  29. package/dist/esm/components/Avatar/Avatar.d.ts.map +1 -1
  30. package/dist/esm/components/Avatar/TokenAvatar.d.ts +1 -2
  31. package/dist/esm/components/Avatar/TokenAvatar.d.ts.map +1 -1
  32. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts +1 -2
  33. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts.map +1 -1
  34. package/dist/esm/components/BaseTransactionButton/types.d.ts +1 -2
  35. package/dist/esm/components/BaseTransactionButton/types.d.ts.map +1 -1
  36. package/dist/esm/components/BottomSheet/BottomSheet.js +1 -0
  37. package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
  38. package/dist/esm/components/BottomSheet/types.d.ts +1 -2
  39. package/dist/esm/components/BottomSheet/types.d.ts.map +1 -1
  40. package/dist/esm/components/ButtonTertiary.d.ts +1 -2
  41. package/dist/esm/components/ButtonTertiary.d.ts.map +1 -1
  42. package/dist/esm/components/Card/CardIconButton.d.ts +1 -2
  43. package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
  44. package/dist/esm/components/Card/CardTitle.d.ts +1 -2
  45. package/dist/esm/components/Card/CardTitle.d.ts.map +1 -1
  46. package/dist/esm/components/Card/InputCard.d.ts +1 -2
  47. package/dist/esm/components/Card/InputCard.d.ts.map +1 -1
  48. package/dist/esm/components/ChainSelect/ChainSelect.d.ts +1 -2
  49. package/dist/esm/components/ChainSelect/ChainSelect.d.ts.map +1 -1
  50. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts +1 -2
  51. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts.map +1 -1
  52. package/dist/esm/components/Chains/AllChainsAvatar.js +7 -1
  53. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
  54. package/dist/esm/components/ContractComponent/ContractComponent.d.ts +1 -2
  55. package/dist/esm/components/ContractComponent/ContractComponent.d.ts.map +1 -1
  56. package/dist/esm/components/ContractComponent/ItemPrice.d.ts +2 -3
  57. package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
  58. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts +1 -2
  59. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts.map +1 -1
  60. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts +1 -2
  61. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts.map +1 -1
  62. package/dist/esm/components/ContractComponent/NFT/types.d.ts +3 -4
  63. package/dist/esm/components/ContractComponent/NFT/types.d.ts.map +1 -1
  64. package/dist/esm/components/Dialog/Dialog.js +2 -1
  65. package/dist/esm/components/Dialog/Dialog.js.map +1 -1
  66. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts +1 -2
  67. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts.map +1 -1
  68. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts +1 -2
  69. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts.map +1 -1
  70. package/dist/esm/components/Expansion/Expansion.js +4 -3
  71. package/dist/esm/components/Expansion/Expansion.js.map +1 -1
  72. package/dist/esm/components/FeeBreakdownTooltip.d.ts +1 -2
  73. package/dist/esm/components/FeeBreakdownTooltip.d.ts.map +1 -1
  74. package/dist/esm/components/Header/SettingsButton.js +2 -1
  75. package/dist/esm/components/Header/SettingsButton.js.map +1 -1
  76. package/dist/esm/components/IconCircle/IconCircle.d.ts +1 -2
  77. package/dist/esm/components/IconCircle/IconCircle.d.ts.map +1 -1
  78. package/dist/esm/components/IconCircle/IconCircle.js +2 -1
  79. package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
  80. package/dist/esm/components/IconCircle/statusIcons.d.ts +1 -2
  81. package/dist/esm/components/IconCircle/statusIcons.d.ts.map +1 -1
  82. package/dist/esm/components/IconTypography.d.ts +1 -2
  83. package/dist/esm/components/IconTypography.d.ts.map +1 -1
  84. package/dist/esm/components/ListItem/ListItemButton.d.ts +1 -2
  85. package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
  86. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js +27 -0
  87. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js.map +1 -0
  88. package/dist/esm/components/Messages/WarningMessages.d.ts +1 -2
  89. package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
  90. package/dist/esm/components/Messages/WarningMessages.js +2 -0
  91. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  92. package/dist/esm/components/Messages/useMessageQueue.js +6 -1
  93. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  94. package/dist/esm/components/PageContainer.d.ts +2 -3
  95. package/dist/esm/components/PageContainer.d.ts.map +1 -1
  96. package/dist/esm/components/PoweredBy/PoweredBy.d.ts +1 -2
  97. package/dist/esm/components/PoweredBy/PoweredBy.d.ts.map +1 -1
  98. package/dist/esm/components/ProgressToNextUpdate.d.ts +1 -2
  99. package/dist/esm/components/ProgressToNextUpdate.d.ts.map +1 -1
  100. package/dist/esm/components/RouteCard/RouteCard.d.ts +1 -2
  101. package/dist/esm/components/RouteCard/RouteCard.d.ts.map +1 -1
  102. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts +1 -2
  103. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts.map +1 -1
  104. package/dist/esm/components/RouteCard/RouteDetails.d.ts +1 -2
  105. package/dist/esm/components/RouteCard/RouteDetails.d.ts.map +1 -1
  106. package/dist/esm/components/RouteCard/RouteDetails.js +2 -1
  107. package/dist/esm/components/RouteCard/RouteDetails.js.map +1 -1
  108. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts +5 -6
  109. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts.map +1 -1
  110. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts +1 -2
  111. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts.map +1 -1
  112. package/dist/esm/components/RouteCard/RouteTokens.d.ts +1 -2
  113. package/dist/esm/components/RouteCard/RouteTokens.d.ts.map +1 -1
  114. package/dist/esm/components/RouteCard/types.d.ts +2 -3
  115. package/dist/esm/components/RouteCard/types.d.ts.map +1 -1
  116. package/dist/esm/components/Routes/LimitOrderRoutes.js +2 -2
  117. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -1
  118. package/dist/esm/components/Routes/RoutesContent.js +2 -2
  119. package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
  120. package/dist/esm/components/Search/SearchInput.d.ts +1 -2
  121. package/dist/esm/components/Search/SearchInput.d.ts.map +1 -1
  122. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts +1 -2
  123. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts.map +1 -1
  124. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +2 -2
  125. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  126. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts +1 -2
  127. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts.map +1 -1
  128. package/dist/esm/components/Skeleton/WidgetSkeleton.js +2 -1
  129. package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
  130. package/dist/esm/components/Step/StepActions.js +18 -16
  131. package/dist/esm/components/Step/StepActions.js.map +1 -1
  132. package/dist/esm/components/StepActions/SentToWalletRow.d.ts +1 -2
  133. package/dist/esm/components/StepActions/SentToWalletRow.d.ts.map +1 -1
  134. package/dist/esm/components/StepActions/StepActionRow.js +2 -1
  135. package/dist/esm/components/StepActions/StepActionRow.js.map +1 -1
  136. package/dist/esm/components/StepActions/StepActionRow.style.d.ts +1 -2
  137. package/dist/esm/components/StepActions/StepActionRow.style.d.ts.map +1 -1
  138. package/dist/esm/components/StepActions/StepActionsList.d.ts +1 -2
  139. package/dist/esm/components/StepActions/StepActionsList.d.ts.map +1 -1
  140. package/dist/esm/components/StepActions/executionRows.d.ts +2 -3
  141. package/dist/esm/components/StepActions/executionRows.d.ts.map +1 -1
  142. package/dist/esm/components/Switch.js +1 -1
  143. package/dist/esm/components/Switch.js.map +1 -1
  144. package/dist/esm/components/Tabs/Tabs.style.js +4 -2
  145. package/dist/esm/components/Tabs/Tabs.style.js.map +1 -1
  146. package/dist/esm/components/Token/Token.d.ts.map +1 -1
  147. package/dist/esm/components/Token/Token.js +2 -4
  148. package/dist/esm/components/Token/Token.js.map +1 -1
  149. package/dist/esm/components/TokenList/RecentTokensHeader.js +44 -0
  150. package/dist/esm/components/TokenList/RecentTokensHeader.js.map +1 -0
  151. package/dist/esm/components/TokenList/RecentTokensToggle.js +36 -0
  152. package/dist/esm/components/TokenList/RecentTokensToggle.js.map +1 -0
  153. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js +32 -0
  154. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js.map +1 -0
  155. package/dist/esm/components/TokenList/TokenList.js +55 -5
  156. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  157. package/dist/esm/components/TokenList/TokenListItem.js +81 -27
  158. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  159. package/dist/esm/components/TokenList/TokenNotFound.d.ts +1 -2
  160. package/dist/esm/components/TokenList/TokenNotFound.d.ts.map +1 -1
  161. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts +1 -2
  162. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
  163. package/dist/esm/components/TokenList/VirtualizedTokenList.js +63 -37
  164. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  165. package/dist/esm/components/TokenList/types.d.ts +9 -2
  166. package/dist/esm/components/TokenList/types.d.ts.map +1 -1
  167. package/dist/esm/components/TokenList/useTokenSelect.d.ts +1 -2
  168. package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
  169. package/dist/esm/components/TokenRate/TokenRate.d.ts +1 -2
  170. package/dist/esm/components/TokenRate/TokenRate.d.ts.map +1 -1
  171. package/dist/esm/components/TokenRate/TokenRate.js +2 -1
  172. package/dist/esm/components/TokenRate/TokenRate.js.map +1 -1
  173. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +22 -21
  174. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
  175. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts +2 -3
  176. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts.map +1 -1
  177. package/dist/esm/config/constants.d.ts +1 -2
  178. package/dist/esm/config/constants.d.ts.map +1 -1
  179. package/dist/esm/config/version.d.ts +2 -3
  180. package/dist/esm/config/version.d.ts.map +1 -1
  181. package/dist/esm/config/version.js +1 -1
  182. package/dist/esm/config/version.js.map +1 -1
  183. package/dist/esm/hooks/timer/time.js +2 -2
  184. package/dist/esm/hooks/timer/time.js.map +1 -1
  185. package/dist/esm/hooks/useAddressActivity.d.ts +1 -2
  186. package/dist/esm/hooks/useAddressActivity.d.ts.map +1 -1
  187. package/dist/esm/hooks/useAddressValidation.d.ts +2 -3
  188. package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
  189. package/dist/esm/hooks/useAvailableChains.d.ts +1 -2
  190. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  191. package/dist/esm/hooks/useAvailableChains.js +2 -1
  192. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  193. package/dist/esm/hooks/useChain.d.ts +1 -2
  194. package/dist/esm/hooks/useChain.d.ts.map +1 -1
  195. package/dist/esm/hooks/useContactSupport.d.ts +1 -2
  196. package/dist/esm/hooks/useContactSupport.d.ts.map +1 -1
  197. package/dist/esm/hooks/useDebouncedWatch.d.ts +1 -2
  198. package/dist/esm/hooks/useDebouncedWatch.d.ts.map +1 -1
  199. package/dist/esm/hooks/useDisplayedTokens.js +6 -4
  200. package/dist/esm/hooks/useDisplayedTokens.js.map +1 -1
  201. package/dist/esm/hooks/useExplorer.d.ts +1 -2
  202. package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
  203. package/dist/esm/hooks/useExplorer.js +4 -0
  204. package/dist/esm/hooks/useExplorer.js.map +1 -1
  205. package/dist/esm/hooks/useFlaggedTokenGuard.js +28 -0
  206. package/dist/esm/hooks/useFlaggedTokenGuard.js.map +1 -0
  207. package/dist/esm/hooks/useGasSufficiency.js +3 -1
  208. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  209. package/dist/esm/hooks/useHeader.d.ts +1 -2
  210. package/dist/esm/hooks/useHeader.d.ts.map +1 -1
  211. package/dist/esm/hooks/useListHeight.d.ts +1 -2
  212. package/dist/esm/hooks/useListHeight.d.ts.map +1 -1
  213. package/dist/esm/hooks/useMaxSendAmount.js +15 -0
  214. package/dist/esm/hooks/useMaxSendAmount.js.map +1 -0
  215. package/dist/esm/hooks/useNavigateBack.d.ts +1 -2
  216. package/dist/esm/hooks/useNavigateBack.d.ts.map +1 -1
  217. package/dist/esm/hooks/usePacedRouteExecution.js +3 -2
  218. package/dist/esm/hooks/usePacedRouteExecution.js.map +1 -1
  219. package/dist/esm/hooks/useRecentTokens.js +46 -0
  220. package/dist/esm/hooks/useRecentTokens.js.map +1 -0
  221. package/dist/esm/hooks/useRouteExecution.d.ts +1 -2
  222. package/dist/esm/hooks/useRouteExecution.d.ts.map +1 -1
  223. package/dist/esm/hooks/useRouteExecutionMessage.d.ts +1 -2
  224. package/dist/esm/hooks/useRouteExecutionMessage.d.ts.map +1 -1
  225. package/dist/esm/hooks/useRouteExecutionMessage.js +3 -2
  226. package/dist/esm/hooks/useRouteExecutionMessage.js.map +1 -1
  227. package/dist/esm/hooks/useRoutes.d.ts +1 -2
  228. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  229. package/dist/esm/hooks/useRoutes.js +8 -1
  230. package/dist/esm/hooks/useRoutes.js.map +1 -1
  231. package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
  232. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  233. package/dist/esm/hooks/useToAddressRequirements.js +13 -1
  234. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  235. package/dist/esm/hooks/useToken.d.ts +1 -2
  236. package/dist/esm/hooks/useToken.d.ts.map +1 -1
  237. package/dist/esm/hooks/useTokenAddressBalance.d.ts +1 -2
  238. package/dist/esm/hooks/useTokenAddressBalance.d.ts.map +1 -1
  239. package/dist/esm/hooks/useTokenBalances.d.ts +3 -2
  240. package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
  241. package/dist/esm/hooks/useTokenBalances.js +19 -8
  242. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  243. package/dist/esm/hooks/useTokenBalancesQueries.js +29 -28
  244. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
  245. package/dist/esm/hooks/useTokenList.d.ts +1 -2
  246. package/dist/esm/hooks/useTokenList.d.ts.map +1 -1
  247. package/dist/esm/hooks/useTokenSearch.js +5 -6
  248. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  249. package/dist/esm/hooks/useTokens.js +40 -25
  250. package/dist/esm/hooks/useTokens.js.map +1 -1
  251. package/dist/esm/hooks/useTools.d.ts +1 -2
  252. package/dist/esm/hooks/useTools.d.ts.map +1 -1
  253. package/dist/esm/hooks/useWideVariant.js +2 -1
  254. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  255. package/dist/esm/hooks/useWidgetChains.d.ts +1 -2
  256. package/dist/esm/hooks/useWidgetChains.d.ts.map +1 -1
  257. package/dist/esm/hooks/useWidgetEvents.d.ts +3 -4
  258. package/dist/esm/hooks/useWidgetEvents.d.ts.map +1 -1
  259. package/dist/esm/i18n/bn.json +7 -1
  260. package/dist/esm/i18n/de.json +7 -1
  261. package/dist/esm/i18n/en.json +16 -3
  262. package/dist/esm/i18n/es.json +7 -1
  263. package/dist/esm/i18n/fr.json +7 -1
  264. package/dist/esm/i18n/hi.json +7 -1
  265. package/dist/esm/i18n/id.json +7 -1
  266. package/dist/esm/i18n/it.json +7 -1
  267. package/dist/esm/i18n/ja.json +7 -1
  268. package/dist/esm/i18n/ko.json +7 -1
  269. package/dist/esm/i18n/pl.json +7 -1
  270. package/dist/esm/i18n/pt.json +7 -1
  271. package/dist/esm/i18n/th.json +7 -1
  272. package/dist/esm/i18n/tr.json +7 -1
  273. package/dist/esm/i18n/uk.json +7 -1
  274. package/dist/esm/i18n/vi.json +7 -1
  275. package/dist/esm/i18n/zh.json +7 -1
  276. package/dist/esm/pages/MainPage/MainPage.js +2 -1
  277. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  278. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts +1 -2
  279. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts.map +1 -1
  280. package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
  281. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  282. package/dist/esm/pages/RoutesPage/RoutesPage.js +2 -2
  283. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  284. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts +1 -2
  285. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts.map +1 -1
  286. package/dist/esm/pages/SelectChainPage/SelectChainPage.js +13 -12
  287. package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  288. package/dist/esm/pages/SelectChainPage/types.d.ts +1 -2
  289. package/dist/esm/pages/SelectChainPage/types.d.ts.map +1 -1
  290. package/dist/esm/pages/SelectEnabledToolsPage.js +8 -5
  291. package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
  292. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -2
  293. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts.map +1 -1
  294. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +2 -1
  295. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  296. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js +2 -1
  297. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
  298. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts +1 -2
  299. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts.map +1 -1
  300. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js +2 -1
  301. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
  302. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +2 -1
  303. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  304. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts +1 -2
  305. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts.map +1 -1
  306. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts +2 -3
  307. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts.map +1 -1
  308. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts +1 -2
  309. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts.map +1 -1
  310. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts +1 -2
  311. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts.map +1 -1
  312. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts +1 -2
  313. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts.map +1 -1
  314. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +4 -3
  315. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  316. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts +1 -2
  317. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts.map +1 -1
  318. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +0 -1
  319. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  320. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +63 -0
  321. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -0
  322. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts +1 -2
  323. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts.map +1 -1
  324. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js +19 -16
  325. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js.map +1 -1
  326. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +38 -10
  327. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
  328. package/dist/esm/pages/TransactionPage/TransactionReview.js +32 -9
  329. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  330. package/dist/esm/pages/TransactionPage/types.d.ts +1 -2
  331. package/dist/esm/pages/TransactionPage/types.d.ts.map +1 -1
  332. package/dist/esm/pages/TransactionPage/utils.d.ts +2 -3
  333. package/dist/esm/pages/TransactionPage/utils.d.ts.map +1 -1
  334. package/dist/esm/pages/TransactionPage/utils.js +23 -1
  335. package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
  336. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts +1 -2
  337. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts.map +1 -1
  338. package/dist/esm/providers/I18nProvider/I18nProvider.js +37 -36
  339. package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  340. package/dist/esm/providers/I18nProvider/types.d.ts +4 -5
  341. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  342. package/dist/esm/providers/QueryClientProvider.d.ts +1 -2
  343. package/dist/esm/providers/QueryClientProvider.d.ts.map +1 -1
  344. package/dist/esm/providers/SDKClientProvider.d.ts +2 -3
  345. package/dist/esm/providers/SDKClientProvider.d.ts.map +1 -1
  346. package/dist/esm/providers/ThemeProvider/ThemeProvider.js +2 -1
  347. package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
  348. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts +1 -2
  349. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
  350. package/dist/esm/providers/WalletProvider/WalletProvider.js +10 -9
  351. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  352. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
  353. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
  354. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts +2 -3
  355. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  356. package/dist/esm/providers/WidgetProvider/types.d.ts +2 -3
  357. package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
  358. package/dist/esm/stores/StoreProvider.d.ts +1 -2
  359. package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
  360. package/dist/esm/stores/StoreProvider.js +10 -6
  361. package/dist/esm/stores/StoreProvider.js.map +1 -1
  362. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts +1 -2
  363. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts.map +1 -1
  364. package/dist/esm/stores/bookmarks/types.d.ts +5 -6
  365. package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
  366. package/dist/esm/stores/chains/ChainOrderStore.d.ts +1 -2
  367. package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
  368. package/dist/esm/stores/chains/ChainOrderStore.js +11 -5
  369. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  370. package/dist/esm/stores/chains/types.d.ts +1 -2
  371. package/dist/esm/stores/chains/types.d.ts.map +1 -1
  372. package/dist/esm/stores/form/types.d.ts +20 -21
  373. package/dist/esm/stores/form/types.d.ts.map +1 -1
  374. package/dist/esm/stores/form/useFieldActions.d.ts +1 -2
  375. package/dist/esm/stores/form/useFieldActions.d.ts.map +1 -1
  376. package/dist/esm/stores/form/useFieldValues.d.ts +1 -2
  377. package/dist/esm/stores/form/useFieldValues.d.ts.map +1 -1
  378. package/dist/esm/stores/header/types.d.ts +1 -2
  379. package/dist/esm/stores/header/types.d.ts.map +1 -1
  380. package/dist/esm/stores/header/useHeaderStore.d.ts +2 -3
  381. package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
  382. package/dist/esm/stores/inputMode/useInputModeStore.d.ts +1 -2
  383. package/dist/esm/stores/inputMode/useInputModeStore.d.ts.map +1 -1
  384. package/dist/esm/stores/recentTokens/RecentTokensStore.js +23 -0
  385. package/dist/esm/stores/recentTokens/RecentTokensStore.js.map +1 -0
  386. package/dist/esm/stores/recentTokens/createRecentTokensStore.js +54 -0
  387. package/dist/esm/stores/recentTokens/createRecentTokensStore.js.map +1 -0
  388. package/dist/esm/stores/recentTokens/utils.js +15 -0
  389. package/dist/esm/stores/recentTokens/utils.js.map +1 -0
  390. package/dist/esm/stores/routes/RouteExecutionStore.d.ts +2 -3
  391. package/dist/esm/stores/routes/RouteExecutionStore.d.ts.map +1 -1
  392. package/dist/esm/stores/routes/types.d.ts +3 -4
  393. package/dist/esm/stores/routes/types.d.ts.map +1 -1
  394. package/dist/esm/stores/routes/useRouteExecutionIndicator.js +4 -3
  395. package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
  396. package/dist/esm/stores/routes/utils.d.ts +4 -5
  397. package/dist/esm/stores/routes/utils.d.ts.map +1 -1
  398. package/dist/esm/stores/settings/SettingsStore.d.ts +2 -3
  399. package/dist/esm/stores/settings/SettingsStore.d.ts.map +1 -1
  400. package/dist/esm/stores/settings/types.d.ts +2 -3
  401. package/dist/esm/stores/settings/types.d.ts.map +1 -1
  402. package/dist/esm/stores/types.d.ts +2 -3
  403. package/dist/esm/stores/types.d.ts.map +1 -1
  404. package/dist/esm/themes/azureLight.d.ts +1 -2
  405. package/dist/esm/themes/azureLight.d.ts.map +1 -1
  406. package/dist/esm/themes/jumper.d.ts +1 -2
  407. package/dist/esm/themes/jumper.d.ts.map +1 -1
  408. package/dist/esm/themes/palettes.d.ts +3 -4
  409. package/dist/esm/themes/palettes.d.ts.map +1 -1
  410. package/dist/esm/themes/types.d.ts +1 -0
  411. package/dist/esm/themes/watermelonLight.d.ts +1 -2
  412. package/dist/esm/themes/watermelonLight.d.ts.map +1 -1
  413. package/dist/esm/themes/windows95.d.ts +1 -2
  414. package/dist/esm/themes/windows95.d.ts.map +1 -1
  415. package/dist/esm/types/events.d.ts +13 -14
  416. package/dist/esm/types/events.d.ts.map +1 -1
  417. package/dist/esm/types/token.d.ts +6 -1
  418. package/dist/esm/types/token.d.ts.map +1 -1
  419. package/dist/esm/types/widget.d.ts +55 -51
  420. package/dist/esm/types/widget.d.ts.map +1 -1
  421. package/dist/esm/types/widget.js.map +1 -1
  422. package/dist/esm/utils/address.js +19 -0
  423. package/dist/esm/utils/address.js.map +1 -0
  424. package/dist/esm/utils/compactNumberFormatter.d.ts +1 -2
  425. package/dist/esm/utils/compactNumberFormatter.d.ts.map +1 -1
  426. package/dist/esm/utils/compactNumberFormatter.js +1 -3
  427. package/dist/esm/utils/compactNumberFormatter.js.map +1 -1
  428. package/dist/esm/utils/converters.d.ts +1 -2
  429. package/dist/esm/utils/converters.d.ts.map +1 -1
  430. package/dist/esm/utils/currencyExtendedFormatter.d.ts +1 -2
  431. package/dist/esm/utils/currencyExtendedFormatter.d.ts.map +1 -1
  432. package/dist/esm/utils/customReceiver.js +12 -0
  433. package/dist/esm/utils/customReceiver.js.map +1 -0
  434. package/dist/esm/utils/elements.d.ts +2 -3
  435. package/dist/esm/utils/elements.d.ts.map +1 -1
  436. package/dist/esm/utils/enum.d.ts +1 -2
  437. package/dist/esm/utils/enum.d.ts.map +1 -1
  438. package/dist/esm/utils/fees.d.ts +2 -3
  439. package/dist/esm/utils/fees.d.ts.map +1 -1
  440. package/dist/esm/utils/format.d.ts +8 -9
  441. package/dist/esm/utils/format.d.ts.map +1 -1
  442. package/dist/esm/utils/gas.js +24 -0
  443. package/dist/esm/utils/gas.js.map +1 -0
  444. package/dist/esm/utils/getErrorMessage.js +0 -1
  445. package/dist/esm/utils/getErrorMessage.js.map +1 -1
  446. package/dist/esm/utils/getPriceImpact.d.ts +1 -2
  447. package/dist/esm/utils/getPriceImpact.d.ts.map +1 -1
  448. package/dist/esm/utils/input.d.ts +1 -2
  449. package/dist/esm/utils/input.d.ts.map +1 -1
  450. package/dist/esm/utils/limitOrder.js +1 -1
  451. package/dist/esm/utils/limitOrder.js.map +1 -1
  452. package/dist/esm/utils/navigationRoutes.d.ts +2 -3
  453. package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
  454. package/dist/esm/utils/percentFormatter.d.ts +1 -2
  455. package/dist/esm/utils/percentFormatter.d.ts.map +1 -1
  456. package/dist/esm/utils/recentTokens.js +97 -0
  457. package/dist/esm/utils/recentTokens.js.map +1 -0
  458. package/dist/esm/utils/token.js +50 -7
  459. package/dist/esm/utils/token.js.map +1 -1
  460. package/dist/esm/utils/tokenList.js +54 -25
  461. package/dist/esm/utils/tokenList.js.map +1 -1
  462. package/dist/esm/utils/tokenListBands.js +85 -0
  463. package/dist/esm/utils/tokenListBands.js.map +1 -0
  464. package/dist/esm/utils/wallet.d.ts +1 -2
  465. package/dist/esm/utils/wallet.d.ts.map +1 -1
  466. package/package.json +15 -15
  467. package/src/components/AmountInput/AmountInputEndAdornment.tsx +2 -21
  468. package/src/components/AmountInputCard/PercentageChips.tsx +2 -18
  469. package/src/components/AmountInputCard/ReceiveAmountCard.tsx +16 -3
  470. package/src/components/BottomSheet/BottomSheet.tsx +3 -0
  471. package/src/components/Chains/AllChainsAvatar.tsx +7 -1
  472. package/src/components/Messages/UnsupportedToAddressMessage.tsx +24 -0
  473. package/src/components/Messages/WarningMessages.tsx +3 -0
  474. package/src/components/Messages/useMessageQueue.ts +9 -0
  475. package/src/components/Routes/LimitOrderRoutes.tsx +5 -2
  476. package/src/components/Routes/RoutesContent.tsx +5 -2
  477. package/src/components/SendToWallet/SendToWalletExpandButton.tsx +2 -1
  478. package/src/components/Token/Token.tsx +2 -1
  479. package/src/components/TokenList/RecentTokensHeader.tsx +52 -0
  480. package/src/components/TokenList/RecentTokensToggle.tsx +45 -0
  481. package/src/components/TokenList/RemoveRecentTokenButton.tsx +38 -0
  482. package/src/components/TokenList/TokenList.tsx +92 -3
  483. package/src/components/TokenList/TokenListItem.tsx +83 -9
  484. package/src/components/TokenList/VirtualizedTokenList.tsx +86 -103
  485. package/src/components/TokenList/types.ts +13 -0
  486. package/src/config/version.ts +1 -1
  487. package/src/hooks/useAvailableChains.ts +1 -0
  488. package/src/hooks/useDisplayedTokens.ts +17 -3
  489. package/src/hooks/useExplorer.ts +2 -0
  490. package/src/hooks/useFlaggedTokenGuard.ts +33 -0
  491. package/src/hooks/useGasSufficiency.ts +9 -1
  492. package/src/hooks/useMaxSendAmount.ts +21 -0
  493. package/src/hooks/useRecentTokens.ts +88 -0
  494. package/src/hooks/useRoutes.ts +10 -0
  495. package/src/hooks/useToAddressRequirements.ts +23 -1
  496. package/src/hooks/useTokenBalances.ts +38 -19
  497. package/src/hooks/useTokenSearch.ts +6 -19
  498. package/src/hooks/useTokens.ts +97 -40
  499. package/src/pages/MainPage/ReviewButton.tsx +6 -2
  500. package/src/pages/RoutesPage/RoutesPage.tsx +5 -2
  501. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +1 -1
  502. package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +93 -0
  503. package/src/pages/TransactionPage/TransactionFailedButtons.tsx +62 -26
  504. package/src/pages/TransactionPage/TransactionReview.tsx +51 -25
  505. package/src/pages/TransactionPage/utils.ts +78 -0
  506. package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
  507. package/src/stores/StoreProvider.tsx +10 -7
  508. package/src/stores/chains/ChainOrderStore.test.tsx +298 -0
  509. package/src/stores/chains/ChainOrderStore.tsx +25 -6
  510. package/src/stores/recentTokens/RecentTokensStore.tsx +39 -0
  511. package/src/stores/recentTokens/createRecentTokensStore.ts +107 -0
  512. package/src/stores/recentTokens/types.ts +37 -0
  513. package/src/stores/recentTokens/utils.ts +18 -0
  514. package/src/types/token.ts +8 -3
  515. package/src/types/widget.ts +5 -0
  516. package/src/utils/address.ts +21 -0
  517. package/src/utils/customReceiver.ts +31 -0
  518. package/src/utils/gas.ts +41 -0
  519. package/src/utils/recentTokens.ts +187 -0
  520. package/src/utils/token.ts +122 -19
  521. package/src/utils/tokenList.ts +60 -14
  522. package/src/utils/tokenListBands.ts +181 -0
@@ -4,7 +4,11 @@ import type { FormType } from '../stores/form/types.js'
4
4
  import { useSettings } from '../stores/settings/useSettings.js'
5
5
  import type { TokenAmount } from '../types/token.js'
6
6
  import { formatTokenPrice } from '../utils/format.js'
7
- import { isSearchMatch, processTokenList } from '../utils/tokenList.js'
7
+ import {
8
+ hoistNativeToken,
9
+ isHoistableNative,
10
+ processTokenList,
11
+ } from '../utils/tokenList.js'
8
12
  import { useAccountsBalancesData } from './useAccountsBalancesData.js'
9
13
  import { useDisplayedTokens } from './useDisplayedTokens.js'
10
14
  import { useTokenBalancesQueries } from './useTokenBalancesQueries.js'
@@ -21,12 +25,15 @@ export const useTokenBalances = (
21
25
  isTokensLoading: boolean
22
26
  isSearchLoading: boolean
23
27
  isBalanceLoading: boolean
28
+ /** Always set; optional so hand-built results of this public shape stay valid. */
29
+ nativeHoisted?: boolean
24
30
  } => {
25
31
  const { hiddenUI, tokens: configTokens } = useWidgetConfig()
26
32
  const {
27
33
  allTokens,
28
34
  displayedTokensList,
29
35
  isPinnedToken,
36
+ matchesSearch,
30
37
  isTokensLoading,
31
38
  isSearchLoading,
32
39
  } = useDisplayedTokens(selectedChainId, formType, isAllNetworks, search)
@@ -73,10 +80,10 @@ export const useTokenBalances = (
73
80
  // Check if token is in displayed list and has amount
74
81
  const isInDisplayedList = displayedTokensSet.has(tokenKey) && token.amount
75
82
  // Check if it matches search (for cached appended tokens)
76
- const matchesSearch = isSearchMatch(token, search)
83
+ const matchesTheSearch = matchesSearch(token)
77
84
 
78
85
  // Filter: only include tokens that match our criteria
79
- if (!isInDisplayedList && !matchesSearch) {
86
+ if (!isInDisplayedList && !matchesTheSearch) {
80
87
  return acc
81
88
  }
82
89
 
@@ -107,33 +114,44 @@ export const useTokenBalances = (
107
114
  }, [
108
115
  allTokensWithBalances,
109
116
  displayedTokensList,
110
- search,
117
+ matchesSearch,
111
118
  selectedChainId,
112
119
  isAllNetworks,
113
120
  smallBalanceThreshold,
114
121
  hiddenUI,
115
122
  ])
116
123
 
117
- const { processedTokens, withCategories, withPinnedTokens } = useMemo(() => {
118
- return processTokenList(
124
+ const { processedTokens, withCategories, withPinnedTokens, nativeHoisted } =
125
+ useMemo(() => {
126
+ const result = processTokenList(
127
+ isBalanceLoading,
128
+ isAllNetworks || !!search,
129
+ configTokens,
130
+ selectedChainId,
131
+ displayedTokensList,
132
+ displayedTokensWithBalances,
133
+ isPinnedToken
134
+ )
135
+ // Search results stay ranked, and All networks has no single native.
136
+ if (isAllNetworks || search) {
137
+ return { ...result, nativeHoisted: false }
138
+ }
139
+ const hoisted = hoistNativeToken(result.processedTokens, selectedChainId)
140
+ return {
141
+ ...result,
142
+ processedTokens: hoisted,
143
+ nativeHoisted: isHoistableNative(hoisted[0], selectedChainId),
144
+ }
145
+ }, [
119
146
  isBalanceLoading,
120
- isAllNetworks || !!search,
147
+ isAllNetworks,
121
148
  configTokens,
122
149
  selectedChainId,
123
150
  displayedTokensList,
124
151
  displayedTokensWithBalances,
125
- isPinnedToken
126
- )
127
- }, [
128
- isBalanceLoading,
129
- isAllNetworks,
130
- configTokens,
131
- selectedChainId,
132
- displayedTokensList,
133
- displayedTokensWithBalances,
134
- search,
135
- isPinnedToken,
136
- ])
152
+ search,
153
+ isPinnedToken,
154
+ ])
137
155
 
138
156
  return {
139
157
  tokens: processedTokens ?? [],
@@ -142,5 +160,6 @@ export const useTokenBalances = (
142
160
  isTokensLoading,
143
161
  isSearchLoading,
144
162
  isBalanceLoading,
163
+ nativeHoisted,
145
164
  }
146
165
  }
@@ -1,16 +1,12 @@
1
- import {
2
- type BaseToken,
3
- type ChainId,
4
- getToken,
5
- type TokenExtended,
6
- } from '@lifi/sdk'
1
+ import { type ChainId, getToken, type TokenExtended } from '@lifi/sdk'
7
2
  import { useQuery, useQueryClient } from '@tanstack/react-query'
8
3
  import { useSDKClient } from '../providers/SDKClientProvider.js'
9
4
  import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
10
5
  import type { FormType } from '../stores/form/types.js'
11
6
  import type { TokensByChain } from '../types/token.js'
12
- import { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'
7
+ import { isFormItemAllowed } from '../utils/item.js'
13
8
  import { getQueryKey } from '../utils/queries.js'
9
+ import { getChainTokenAllowSets } from '../utils/token.js'
14
10
 
15
11
  export const useTokenSearch = (
16
12
  chainId?: number,
@@ -39,14 +35,9 @@ export const useTokenSearch = (
39
35
 
40
36
  if (token) {
41
37
  // Filter config tokens by chain before checking if token is allowed
42
- const filteredConfigTokens = getConfigItemSets(
38
+ const filteredConfigTokens = getChainTokenAllowSets(
43
39
  configTokens,
44
- (tokens: BaseToken[]) =>
45
- new Set(
46
- tokens
47
- .filter((t) => t.chainId === token.chainId)
48
- .map((t) => t.address.toLowerCase())
49
- ),
40
+ token.chainId,
50
41
  formType
51
42
  )
52
43
 
@@ -74,13 +65,9 @@ export const useTokenSearch = (
74
65
  ) {
75
66
  return data
76
67
  }
77
- // Mark token from search as unverified
78
68
  return {
79
69
  ...data,
80
- [chainId as number]: [
81
- ...(chainTokens ?? []),
82
- { ...token, verified: false },
83
- ],
70
+ [chainId as number]: [...(chainTokens ?? []), token],
84
71
  }
85
72
  }
86
73
  )
@@ -12,13 +12,16 @@ import { useSDKClient } from '../providers/SDKClientProvider.js'
12
12
  import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
13
13
  import type { FormType } from '../stores/form/types.js'
14
14
  import type { TokensByChain } from '../types/token.js'
15
+ import { isAddressQuery } from '../utils/address.js'
15
16
  import { defaultChainIdsByType } from '../utils/chainType.js'
16
17
  import { isItemAllowed } from '../utils/item.js'
17
18
  import { getQueryKey } from '../utils/queries.js'
18
19
  import {
19
20
  filterAllowedTokens,
21
+ getNativeTokenAddresses,
20
22
  mergeVerifiedWithSearchTokens,
21
23
  } from '../utils/token.js'
24
+ import { useAvailableChains } from './useAvailableChains.js'
22
25
 
23
26
  const refetchInterval = 300_000
24
27
 
@@ -30,6 +33,8 @@ export const useTokens = (
30
33
  allTokens: Record<number, TokenExtended[]> | undefined
31
34
  isLoading: boolean
32
35
  isSearchLoading: boolean
36
+ /** The search is a contract address, so only the token at that address matches. */
37
+ isAddressSearch: boolean
33
38
  } => {
34
39
  const {
35
40
  tokens: configTokens,
@@ -37,7 +42,16 @@ export const useTokens = (
37
42
  keyPrefix,
38
43
  } = useWidgetConfig()
39
44
  const sdkClient = useSDKClient()
40
- const { getChainTypeFromAddress } = useChainTypeFromAddress()
45
+ const { getChainTypeFromTokenAddress } = useChainTypeFromAddress()
46
+ // A pasted address often carries a trailing space or newline, which the
47
+ // API rejects. Trim once so the key, the requests and the checks agree.
48
+ const trimmedSearch = search?.trim()
49
+ // Keep this memoized, and out of any per-token loop: a provider validates by
50
+ // parsing, which costs microseconds per call rather than nanoseconds.
51
+ const isAddressSearch = useMemo(
52
+ () => isAddressQuery(trimmedSearch, getChainTypeFromTokenAddress),
53
+ [trimmedSearch, getChainTypeFromTokenAddress]
54
+ )
41
55
 
42
56
  // Main tokens cache - verified tokens from API
43
57
  const { data: verifiedTokens, isLoading } = useQuery({
@@ -49,6 +63,7 @@ export const useTokens = (
49
63
  ChainType.UTXO,
50
64
  ChainType.MVM,
51
65
  ChainType.TVM,
66
+ ChainType.STL,
52
67
  ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))
53
68
 
54
69
  const tokensResponse: TokensExtendedResponse = await getTokens(
@@ -63,11 +78,11 @@ export const useTokens = (
63
78
  { signal }
64
79
  )
65
80
 
66
- // Mark all tokens as verified
81
+ // `listed` tells a main-list token from a searched one
67
82
  const tokens: TokensByChain = Object.fromEntries(
68
83
  Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [
69
84
  chainId,
70
- tokens.map((token) => ({ ...token, verified: true })),
85
+ tokens.map((token) => ({ ...token, listed: true })),
71
86
  ])
72
87
  )
73
88
 
@@ -79,19 +94,21 @@ export const useTokens = (
79
94
 
80
95
  // Search tokens cache - unverified tokens from search
81
96
  const { data: searchTokens, isLoading: isSearchLoading } = useQuery({
82
- queryKey: [getQueryKey('tokens-search', keyPrefix), search, chainId],
97
+ queryKey: [
98
+ getQueryKey('tokens-search', keyPrefix),
99
+ trimmedSearch,
100
+ chainId,
101
+ isAddressSearch,
102
+ ] as const,
83
103
  queryFn: async ({ queryKey, signal }) => {
84
- const [, searchQuery, searchChainId] = queryKey as [
85
- string,
86
- string,
87
- number,
88
- ]
104
+ const [, searchQuery, searchChainId, addressSearch] = queryKey
89
105
  const chainTypes = [
90
106
  ChainType.EVM,
91
107
  ChainType.SVM,
92
108
  ChainType.UTXO,
93
109
  ChainType.MVM,
94
110
  ChainType.TVM,
111
+ ChainType.STL,
95
112
  ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))
96
113
 
97
114
  const tokensResponse: TokensExtendedResponse = await getTokens(
@@ -107,53 +124,93 @@ export const useTokens = (
107
124
  { signal }
108
125
  )
109
126
 
110
- // If the chainId is not provided, try to get it from the search query
111
- let _chainId = searchChainId
112
- if (!_chainId) {
113
- const chainType = getChainTypeFromAddress(searchQuery)
114
- if (chainType && chainType in defaultChainIdsByType) {
115
- _chainId = defaultChainIdsByType[chainType]
116
- }
117
- }
118
-
119
- // Fallback: If the main search returned no tokens for the specific chainId,
120
- // fetch a single token using the /token endpoint
121
- if (_chainId && searchQuery) {
122
- const existingTokens = tokensResponse.tokens[_chainId] || []
123
- if (!existingTokens.length) {
124
- const token = await getToken(sdkClient, _chainId, searchQuery, {
125
- signal,
126
- })
127
- if (token) {
128
- tokensResponse.tokens[_chainId] = [token]
127
+ // Fallback: fetch a single token from the /token endpoint when the
128
+ // search did not deliver one. Look it up on the selected chain, or
129
+ // without one on the default chain of the address format.
130
+ if (searchQuery) {
131
+ const chainType = getChainTypeFromTokenAddress(searchQuery)
132
+ const lookupChainId =
133
+ searchChainId ??
134
+ (chainType ? defaultChainIdsByType[chainType] : undefined)
135
+ if (lookupChainId) {
136
+ const existingTokens = tokensResponse.tokens[lookupChainId] ?? []
137
+ // The search index also matches names, so for an address query
138
+ // impersonators that embed the address can fill the list while the
139
+ // token at that address is missing. Without a selected chain the
140
+ // token can sit on any chain of the response.
141
+ const hasTokenAtAddress = () => {
142
+ const address = searchQuery.toLowerCase()
143
+ const candidates = searchChainId
144
+ ? [existingTokens]
145
+ : Object.values(tokensResponse.tokens)
146
+ return candidates.some((tokens) =>
147
+ tokens.some((token) => token.address?.toLowerCase() === address)
148
+ )
149
+ }
150
+ const isTokenMissing = addressSearch
151
+ ? !hasTokenAtAddress()
152
+ : !existingTokens.length
153
+ if (isTokenMissing) {
154
+ try {
155
+ const token = await getToken(
156
+ sdkClient,
157
+ lookupChainId,
158
+ searchQuery,
159
+ { signal }
160
+ )
161
+ if (token) {
162
+ tokensResponse.tokens[lookupChainId] = [
163
+ ...existingTokens,
164
+ token,
165
+ ]
166
+ }
167
+ } catch (error) {
168
+ // A guessed chain may not hold the token (HTTP 400). Keep the
169
+ // search results instead of failing the whole query.
170
+ if (signal.aborted) {
171
+ throw error
172
+ }
173
+ }
129
174
  }
130
175
  }
131
176
  }
132
177
 
133
- // Mark all search tokens as unverified
134
- const tokens: TokensByChain = Object.fromEntries(
135
- Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [
136
- chainId,
137
- tokens.map((token) => ({ ...token, verified: false })),
138
- ])
139
- )
140
-
141
- return tokens
178
+ return tokensResponse.tokens as TokensByChain
142
179
  },
143
- enabled: !!search,
180
+ enabled: !!trimmedSearch,
144
181
  refetchInterval,
145
182
  staleTime: refetchInterval,
146
183
  })
147
184
 
185
+ const { chains } = useAvailableChains()
186
+ const nativeTokenAddresses = useMemo(
187
+ () => getNativeTokenAddresses(chains),
188
+ [chains]
189
+ )
190
+
148
191
  // Merge tokens at read time - single place where caches are combined
149
192
  const allTokens = useMemo(() => {
150
193
  const merged = mergeVerifiedWithSearchTokens(verifiedTokens, searchTokens)
151
- return filterAllowedTokens(merged, configTokens, chainsConfig, formType)
152
- }, [verifiedTokens, searchTokens, configTokens, chainsConfig, formType])
194
+ return filterAllowedTokens(
195
+ merged,
196
+ configTokens,
197
+ chainsConfig,
198
+ formType,
199
+ nativeTokenAddresses
200
+ )
201
+ }, [
202
+ verifiedTokens,
203
+ searchTokens,
204
+ configTokens,
205
+ chainsConfig,
206
+ formType,
207
+ nativeTokenAddresses,
208
+ ])
153
209
 
154
210
  return {
155
211
  allTokens,
156
212
  isLoading,
157
213
  isSearchLoading,
214
+ isAddressSearch,
158
215
  }
159
216
  }
@@ -16,7 +16,8 @@ export const ReviewButton: React.FC = () => {
16
16
  const emitter = useWidgetEvents()
17
17
  const { mode, modeOptions } = useWidgetConfig()
18
18
  const splitState = useSplitMode()
19
- const { toAddress, requiredToAddress } = useToAddressRequirements()
19
+ const { toAddress, requiredToAddress, unsupportedReceiverBlocking } =
20
+ useToAddressRequirements()
20
21
  const { routes, setReviewableRoute } = useRoutes()
21
22
  const [selectedRouteId] = useFieldValues('selectedRouteId')
22
23
 
@@ -85,7 +86,10 @@ export const ReviewButton: React.FC = () => {
85
86
  <BaseTransactionButton
86
87
  text={getButtonText()}
87
88
  onClick={handleClick}
88
- disabled={currentRoute && requiredToAddress && !toAddress}
89
+ disabled={
90
+ currentRoute &&
91
+ (unsupportedReceiverBlocking || (requiredToAddress && !toAddress))
92
+ }
89
93
  route={currentRoute}
90
94
  sx={{ flex: 1 }}
91
95
  />
@@ -36,7 +36,8 @@ export const RoutesPage = (): JSX.Element => {
36
36
  } = useRoutes()
37
37
  const { account } = useAccount({ chainType: fromChain?.chainType })
38
38
  const [toAddress] = useFieldValues('toAddress')
39
- const { requiredToAddress } = useToAddressRequirements()
39
+ const { requiredToAddress, unsupportedReceiverBlocking } =
40
+ useToAddressRequirements()
40
41
 
41
42
  const headerAction = useMemo(
42
43
  () => (
@@ -72,7 +73,9 @@ export const RoutesPage = (): JSX.Element => {
72
73
 
73
74
  const routeNotFound = !routes?.length && !isLoading && !isFetching
74
75
 
75
- const toAddressUnsatisfied = routes?.[0] && requiredToAddress && !toAddress
76
+ const toAddressUnsatisfied =
77
+ routes?.[0] &&
78
+ (unsupportedReceiverBlocking || (requiredToAddress && !toAddress))
76
79
 
77
80
  const allowInteraction = account.isConnected && !toAddressUnsatisfied
78
81
 
@@ -36,8 +36,8 @@ export const TokenValueBottomSheet = ({
36
36
  ref?: Ref<BottomSheetBase>
37
37
  }): JSX.Element => {
38
38
  const handleCancel = () => {
39
+ // close() reaches onClose, which is onCancel
39
40
  ;(ref as RefObject<BottomSheetBase>).current?.close()
40
- onCancel?.()
41
41
  }
42
42
 
43
43
  return (
@@ -0,0 +1,93 @@
1
+ import type { Token } from '@lifi/sdk'
2
+ import { Button, Checkbox, FormControlLabel } from '@mui/material'
3
+ import type { JSX, Ref, RefObject } from 'react'
4
+ import { useRef, useState } from 'react'
5
+ import { useTranslation } from 'react-i18next'
6
+ import { BottomSheet } from '../../components/BottomSheet/BottomSheet.js'
7
+ import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
8
+ import { IconCircle } from '../../components/IconCircle/IconCircle.js'
9
+ import { useSetContentHeight } from '../../hooks/useSetContentHeight.js'
10
+ import {
11
+ ButtonRow,
12
+ CenterContainer,
13
+ ContentContainer,
14
+ WarningMessage,
15
+ WarningTitle,
16
+ } from './TokenValueBottomSheet.style.js'
17
+
18
+ interface TokenVerificationBottomSheetProps {
19
+ /** Source and/or destination tokens the screening provider flagged. */
20
+ tokens: Token[]
21
+ onContinue(): void
22
+ onCancel?(): void
23
+ }
24
+
25
+ export const TokenVerificationBottomSheet = ({
26
+ tokens,
27
+ onContinue,
28
+ onCancel,
29
+ ref,
30
+ }: TokenVerificationBottomSheetProps & {
31
+ ref?: Ref<BottomSheetBase>
32
+ }): JSX.Element => {
33
+ const handleCancel = () => {
34
+ // close() reaches onClose, which is onCancel
35
+ ;(ref as RefObject<BottomSheetBase>).current?.close()
36
+ }
37
+
38
+ return (
39
+ <BottomSheet ref={ref} onClose={onCancel}>
40
+ <TokenVerificationBottomSheetContent
41
+ tokens={tokens}
42
+ onContinue={onContinue}
43
+ onCancel={handleCancel}
44
+ />
45
+ </BottomSheet>
46
+ )
47
+ }
48
+
49
+ const TokenVerificationBottomSheetContent: React.FC<
50
+ TokenVerificationBottomSheetProps
51
+ > = ({ tokens, onCancel, onContinue }) => {
52
+ const [accepted, setAccepted] = useState(false)
53
+ const { t } = useTranslation()
54
+ const ref = useRef<HTMLElement>(null)
55
+ useSetContentHeight(ref)
56
+
57
+ return (
58
+ <ContentContainer ref={ref}>
59
+ <CenterContainer>
60
+ <IconCircle status="error" sx={{ mb: 2.5 }} />
61
+ <WarningTitle>{t('warning.title.tokenFlagged')}</WarningTitle>
62
+ </CenterContainer>
63
+ {tokens.map((token) => (
64
+ <WarningMessage key={`${token.chainId}-${token.address}`}>
65
+ {t('warning.message.tokenFlagged', { tokenSymbol: token.symbol })}
66
+ </WarningMessage>
67
+ ))}
68
+ <FormControlLabel
69
+ control={
70
+ <Checkbox
71
+ checked={accepted}
72
+ onChange={(_, checked) => setAccepted(checked)}
73
+ />
74
+ }
75
+ label={t('warning.checkbox.tokenFlagged')}
76
+ sx={{ mt: 1 }}
77
+ />
78
+ <ButtonRow>
79
+ <Button variant="text" onClick={onCancel} fullWidth>
80
+ {t('button.cancel')}
81
+ </Button>
82
+ <Button
83
+ variant="contained"
84
+ onClick={onContinue}
85
+ disabled={!accepted}
86
+ fullWidth
87
+ >
88
+ {t('button.continue')}
89
+ </Button>
90
+ </ButtonRow>
91
+ </ContentContainer>
92
+ )
93
+ }
@@ -5,12 +5,20 @@ import { useTranslation } from 'react-i18next'
5
5
  import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
6
6
  import { useAddressActivity } from '../../hooks/useAddressActivity.js'
7
7
  import { useNavigateBack } from '../../hooks/useNavigateBack.js'
8
+ import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
8
9
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
10
+ import { WidgetEvent } from '../../types/events.js'
9
11
  import { getAccumulatedFeeCostsBreakdown } from '../../utils/fees.js'
10
12
  import { ConfirmToAddressSheet } from './ConfirmToAddressSheet.js'
11
13
  import { StartTransactionButton } from './StartTransactionButton.js'
12
14
  import { TokenValueBottomSheet } from './TokenValueBottomSheet.js'
13
- import { getTokenValueLossThreshold } from './utils.js'
15
+ import type { RetryGate } from './utils.js'
16
+ import {
17
+ calculateValueLossPercentage,
18
+ getRetryGates,
19
+ getTokenValueLossThreshold,
20
+ openNextGate,
21
+ } from './utils.js'
14
22
 
15
23
  interface TransactionFailedButtonsProps {
16
24
  route: RouteExtended
@@ -22,6 +30,7 @@ export const TransactionFailedButtons: React.FC<
22
30
  TransactionFailedButtonsProps
23
31
  > = ({ route, restartRoute, deleteRoute }) => {
24
32
  const { t } = useTranslation()
33
+ const emitter = useWidgetEvents()
25
34
  const navigateBack = useNavigateBack()
26
35
  const { mode, hiddenUI } = useWidgetConfig()
27
36
 
@@ -40,34 +49,61 @@ export const TransactionFailedButtons: React.FC<
40
49
  deleteRoute()
41
50
  }
42
51
 
43
- const handleRetryClick = () => {
44
- if (
45
- toAddress &&
46
- !hasActivity &&
47
- !isLoadingAddressActivity &&
48
- isActivityAddressFetched &&
49
- !hiddenUI?.lowAddressActivityConfirmation
50
- ) {
51
- confirmToAddressSheetRef.current?.open()
52
- return
53
- }
54
-
52
+ const retryGates = (() => {
55
53
  const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)
56
- const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)
57
- const toAmountUSD = Number.parseFloat(route.toAmountUSD)
58
- const tokenValueLossThresholdExceeded = getTokenValueLossThreshold(
59
- fromAmountUSD,
60
- toAmountUSD,
61
- gasCostUSD,
62
- feeCostUSD
54
+ return getRetryGates({
55
+ toAddress,
56
+ hasActivity,
57
+ isLoadingAddressActivity,
58
+ isActivityAddressFetched,
59
+ confirmationHidden: Boolean(hiddenUI?.lowAddressActivityConfirmation),
60
+ valueLossExceeded: getTokenValueLossThreshold(
61
+ Number.parseFloat(route.fromAmountUSD),
62
+ Number.parseFloat(route.toAmountUSD),
63
+ gasCostUSD,
64
+ feeCostUSD
65
+ ),
66
+ isCustomMode: mode === 'custom',
67
+ })
68
+ })()
69
+
70
+ const openGate = (after?: RetryGate) =>
71
+ openNextGate(
72
+ retryGates,
73
+ {
74
+ address: () => confirmToAddressSheetRef.current?.open(),
75
+ value: () => tokenValueBottomSheetRef.current?.open(),
76
+ },
77
+ handleRestartRoute,
78
+ after
63
79
  )
64
- if (tokenValueLossThresholdExceeded && mode !== 'custom') {
65
- tokenValueBottomSheetRef.current?.open()
66
- } else {
67
- restartRoute()
80
+
81
+ const handleRestartRoute = () => {
82
+ if (tokenValueBottomSheetRef.current?.isOpen()) {
83
+ const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)
84
+ const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)
85
+ const toAmountUSD = Number.parseFloat(route.toAmountUSD)
86
+ emitter.emit(WidgetEvent.RouteHighValueLoss, {
87
+ fromAmountUSD,
88
+ toAmountUSD,
89
+ gasCostUSD,
90
+ feeCostUSD,
91
+ valueLoss: calculateValueLossPercentage(
92
+ fromAmountUSD,
93
+ toAmountUSD,
94
+ gasCostUSD,
95
+ feeCostUSD
96
+ ),
97
+ })
68
98
  }
99
+ tokenValueBottomSheetRef.current?.close()
100
+ restartRoute()
69
101
  }
70
102
 
103
+ const handleRetryClick = () => openGate()
104
+
105
+ const handleConfirmToAddressContinue = () => openGate('address')
106
+
71
107
  return (
72
108
  <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
73
109
  <Box sx={{ display: 'flex', gap: 1.5 }}>
@@ -89,13 +125,13 @@ export const TransactionFailedButtons: React.FC<
89
125
  <TokenValueBottomSheet
90
126
  route={route}
91
127
  ref={tokenValueBottomSheetRef}
92
- onContinue={restartRoute}
128
+ onContinue={handleRestartRoute}
93
129
  />
94
130
  ) : null}
95
131
  {!hiddenUI?.lowAddressActivityConfirmation ? (
96
132
  <ConfirmToAddressSheet
97
133
  ref={confirmToAddressSheetRef}
98
- onContinue={restartRoute}
134
+ onContinue={handleConfirmToAddressContinue}
99
135
  toAddress={toAddress!}
100
136
  toChainId={route.toChainId!}
101
137
  />