@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
@@ -0,0 +1,107 @@
1
+ import type { StoreApi, UseBoundStore } from 'zustand'
2
+ import { create } from 'zustand'
3
+ import { persist } from 'zustand/middleware'
4
+ import type { PersistStoreProps } from '../types.js'
5
+ import type {
6
+ RecentToken,
7
+ RecentTokensProps,
8
+ RecentTokensState,
9
+ } from './types.js'
10
+ import { getTokenKey } from './utils.js'
11
+
12
+ const recentTokensLimit = 10
13
+
14
+ const isStoredRecentToken = (value: unknown): value is RecentToken => {
15
+ const token = value as Partial<RecentToken> | null
16
+ return (
17
+ typeof token === 'object' &&
18
+ token !== null &&
19
+ typeof token.chainId === 'number' &&
20
+ typeof token.address === 'string' &&
21
+ typeof token.symbol === 'string' &&
22
+ typeof token.name === 'string' &&
23
+ typeof token.decimals === 'number' &&
24
+ (token.logoURI === undefined || typeof token.logoURI === 'string') &&
25
+ (token.flagged === undefined || typeof token.flagged === 'boolean')
26
+ )
27
+ }
28
+
29
+ // The key lives on the integrator's origin, so its content is untrusted.
30
+ const sanitizeRecentTokens = (stored: unknown): RecentToken[] => {
31
+ if (!Array.isArray(stored)) {
32
+ return []
33
+ }
34
+ const seen = new Set<string>()
35
+ const recentTokens: RecentToken[] = []
36
+ for (const token of stored) {
37
+ if (!isStoredRecentToken(token)) {
38
+ continue
39
+ }
40
+ const key = getTokenKey(token.chainId, token.address)
41
+ if (!seen.has(key)) {
42
+ seen.add(key)
43
+ recentTokens.push(token)
44
+ }
45
+ }
46
+ return recentTokens.slice(0, recentTokensLimit)
47
+ }
48
+
49
+ export const createRecentTokensStore = ({
50
+ namePrefix,
51
+ }: PersistStoreProps): UseBoundStore<StoreApi<RecentTokensState>> =>
52
+ create<RecentTokensState>()(
53
+ persist(
54
+ (set, get) => ({
55
+ recentTokens: [],
56
+ addRecentToken: (token) => {
57
+ const key = getTokenKey(token.chainId, token.address)
58
+ set((state) => ({
59
+ recentTokens: [
60
+ token,
61
+ ...state.recentTokens.filter(
62
+ (t) => getTokenKey(t.chainId, t.address) !== key
63
+ ),
64
+ ].slice(0, recentTokensLimit),
65
+ }))
66
+ },
67
+ removeRecentToken: (chainId, address) => {
68
+ const key = getTokenKey(chainId, address)
69
+ set((state) => ({
70
+ recentTokens: state.recentTokens.filter(
71
+ (t) => getTokenKey(t.chainId, t.address) !== key
72
+ ),
73
+ }))
74
+ },
75
+ clearRecentTokens: (entries) =>
76
+ set((state) => {
77
+ const removed = new Set(
78
+ entries.map((e) => getTokenKey(e.chainId, e.address))
79
+ )
80
+ return {
81
+ recentTokens: state.recentTokens.filter(
82
+ (t) => !removed.has(getTokenKey(t.chainId, t.address))
83
+ ),
84
+ }
85
+ }),
86
+ isRecentToken: (chainId, address) => {
87
+ const key = getTokenKey(chainId, address)
88
+ return get().recentTokens.some(
89
+ (t) => getTokenKey(t.chainId, t.address) === key
90
+ )
91
+ },
92
+ }),
93
+ {
94
+ name: `${namePrefix || 'li.fi'}-recent-tokens`,
95
+ version: 0,
96
+ partialize: (state) => ({
97
+ recentTokens: state.recentTokens,
98
+ }),
99
+ merge: (persisted, current) => ({
100
+ ...current,
101
+ recentTokens: sanitizeRecentTokens(
102
+ (persisted as Partial<RecentTokensProps> | undefined)?.recentTokens
103
+ ),
104
+ }),
105
+ }
106
+ )
107
+ )
@@ -0,0 +1,37 @@
1
+ import type { StoreApi } from 'zustand'
2
+ import type { UseBoundStoreWithEqualityFn } from 'zustand/traditional'
3
+
4
+ export interface RecentToken {
5
+ chainId: number
6
+ /** The token's own casing. Compared case-insensitively with chainId. */
7
+ address: string
8
+ symbol: string
9
+ name: string
10
+ decimals: number
11
+ logoURI?: string
12
+ flagged?: boolean
13
+ }
14
+
15
+ /** Compared case-insensitively. */
16
+ export interface RecentTokenId {
17
+ chainId: number
18
+ address: string
19
+ }
20
+
21
+ export interface RecentTokensProps {
22
+ recentTokens: RecentToken[]
23
+ }
24
+
25
+ export interface RecentTokensActions {
26
+ addRecentToken: (token: RecentToken) => void
27
+ removeRecentToken: (chainId: number, address: string) => void
28
+ /** Removes exactly these entries, never one outside the band's scope. */
29
+ clearRecentTokens: (entries: RecentTokenId[]) => void
30
+ isRecentToken: (chainId: number, address: string) => boolean
31
+ }
32
+
33
+ export type RecentTokensState = RecentTokensProps & RecentTokensActions
34
+
35
+ export type RecentTokensStore = UseBoundStoreWithEqualityFn<
36
+ StoreApi<RecentTokensState>
37
+ >
@@ -0,0 +1,18 @@
1
+ import type { TokenAmount } from '../../types/token.js'
2
+ import type { RecentToken } from './types.js'
3
+
4
+ export const getTokenKey = (chainId: number, address: string): string =>
5
+ `${chainId}-${address.toLowerCase()}`
6
+
7
+ // No price, and no verdict but a flag: a stale "verified" would hide a warning.
8
+ export const toRecentToken = (token: TokenAmount): RecentToken => ({
9
+ // Plain-JS configs can pass a string chainId or null fields; hydration rejects both.
10
+ chainId: Number(token.chainId),
11
+ // Keep the casing: the form and the selected check compare it exactly.
12
+ address: token.address,
13
+ symbol: token.symbol,
14
+ name: token.name ?? '',
15
+ decimals: token.decimals,
16
+ logoURI: token.logoURI ?? undefined,
17
+ flagged: token.verificationStatus === 'flagged' || undefined,
18
+ })
@@ -4,11 +4,16 @@ import type {
4
4
  TokenExtended,
5
5
  } from '@lifi/sdk'
6
6
 
7
- interface TokenFlags {
7
+ export interface TokenFlags {
8
8
  featured?: boolean
9
9
  popular?: boolean
10
10
  pinned?: boolean
11
+ /** A copy promoted into the "Recent searches" band. */
12
+ recent?: boolean
11
13
  verified?: boolean
14
+ native?: boolean
15
+ /** Came from the main token list rather than from a search. */
16
+ listed?: boolean
12
17
  }
13
18
 
14
19
  export interface TokenAmount extends SDKTokenAmount, TokenFlags {}
@@ -17,5 +22,5 @@ export interface TokenAmountExtended
17
22
  extends SDKTokenAmountExtended,
18
23
  TokenFlags {}
19
24
 
20
- export type TokenWithVerified = TokenExtended & { verified?: boolean }
21
- export type TokensByChain = Record<number, TokenWithVerified[]>
25
+ export type TokenWithFlags = TokenExtended & TokenFlags
26
+ export type TokensByChain = Record<number, TokenWithFlags[]>
@@ -156,6 +156,11 @@ export interface HiddenUIConfig {
156
156
  */
157
157
  lowAddressActivityConfirmation?: boolean
158
158
  poweredBy?: boolean
159
+ /**
160
+ * Hide the "Recent searches" section in the token select view.
161
+ * @default false
162
+ */
163
+ recentSearches?: boolean
159
164
  reverseTokensButton?: boolean
160
165
  routeCardPriceImpact?: boolean
161
166
  routeTokenDescription?: boolean
@@ -0,0 +1,21 @@
1
+ import type { ChainType } from '@lifi/sdk'
2
+
3
+ /**
4
+ * True when a token search query is a contract address rather than free text.
5
+ * `getChainTypeFromTokenAddress` asks the configured providers' own
6
+ * `isTokenAddress` (see `useChainTypeFromAddress`), so it covers the token
7
+ * identifier of every ecosystem. Two consequences follow. `bitcoin` stays a
8
+ * name search, because the Bitcoin provider implements no token check. And an
9
+ * ecosystem is not detected unless the host configures its provider from
10
+ * `@lifi/sdk` 4.7.0 or later, even when its chains are listed.
11
+ */
12
+ export const isAddressQuery = (
13
+ query: string | undefined,
14
+ getChainTypeFromTokenAddress: (address: string) => ChainType | undefined
15
+ ): boolean => {
16
+ const value = query?.trim()
17
+ if (!value) {
18
+ return false
19
+ }
20
+ return getChainTypeFromTokenAddress(value) !== undefined
21
+ }
@@ -0,0 +1,31 @@
1
+ import { ChainType } from '@lifi/sdk'
2
+
3
+ // Stellar routes always settle to the account that signs them.
4
+ export const isCustomReceiverUnsupported = (
5
+ fromChainType?: ChainType,
6
+ toChainType?: ChainType
7
+ ): boolean => fromChainType === ChainType.STL && toChainType === ChainType.STL
8
+
9
+ export interface CustomReceiverBlockedArgs {
10
+ fromChainType?: ChainType
11
+ toChainType?: ChainType
12
+ toAddress?: string
13
+ signerAddress?: string
14
+ receiverRequired?: boolean
15
+ }
16
+
17
+ export const isCustomReceiverBlocked = ({
18
+ fromChainType,
19
+ toChainType,
20
+ toAddress,
21
+ signerAddress,
22
+ receiverRequired,
23
+ }: CustomReceiverBlockedArgs): boolean => {
24
+ if (!isCustomReceiverUnsupported(fromChainType, toChainType)) {
25
+ return false
26
+ }
27
+ if (!toAddress) {
28
+ return Boolean(receiverRequired)
29
+ }
30
+ return toAddress.toLowerCase() !== signerAddress?.toLowerCase()
31
+ }
@@ -0,0 +1,41 @@
1
+ import type { LiFiStepExtended, RouteExtended } from '@lifi/sdk'
2
+ import { ChainType } from '@lifi/sdk'
3
+
4
+ /**
5
+ * Returns how much of a step's gas token the route itself delivers before that
6
+ * step runs. The previous step must output the gas token on the same chain, and
7
+ * whatever this step consumes as input is not available for gas.
8
+ * Stellar routes only — they bridge XLM to the receiver and hold back a buffer
9
+ * for the account reserve and the destination step fees.
10
+ */
11
+ export const getSelfFundedGasAmount = (
12
+ route: RouteExtended,
13
+ step: LiFiStepExtended,
14
+ gasChainType?: ChainType
15
+ ): bigint => {
16
+ // TODO: remove the chain gate when the backend reserves gas on every chain
17
+ if (gasChainType !== ChainType.STL) {
18
+ return 0n
19
+ }
20
+ const gasToken = step.estimate.gasCosts?.[0]?.token
21
+ const previousStep = route.steps[route.steps.indexOf(step) - 1]
22
+ if (!gasToken || !previousStep) {
23
+ return 0n
24
+ }
25
+ const { toToken } = previousStep.action
26
+ if (
27
+ toToken.chainId !== gasToken.chainId ||
28
+ toToken.address.toLowerCase() !== gasToken.address.toLowerCase()
29
+ ) {
30
+ return 0n
31
+ }
32
+ const deliveredAmount = BigInt(previousStep.estimate.toAmountMin)
33
+ const consumedAmount =
34
+ step.action.fromToken.address.toLowerCase() ===
35
+ gasToken.address.toLowerCase()
36
+ ? BigInt(step.action.fromAmount)
37
+ : 0n
38
+ return deliveredAmount > consumedAmount
39
+ ? deliveredAmount - consumedAmount
40
+ : 0n
41
+ }
@@ -0,0 +1,187 @@
1
+ import type { FormType } from '../stores/form/types.js'
2
+ import type {
3
+ RecentToken,
4
+ RecentTokenId,
5
+ } from '../stores/recentTokens/types.js'
6
+ import { getTokenKey } from '../stores/recentTokens/utils.js'
7
+ import type { TokenAmount } from '../types/token.js'
8
+ import type { AllowDenySets, WidgetTokens } from '../types/widget.js'
9
+ import { isFormItemAllowed } from './item.js'
10
+ import { getChainTokenAllowSets } from './token.js'
11
+
12
+ export const collapsedRecentCount = 4
13
+
14
+ export interface ResolveRecentRowsParams {
15
+ recentTokens: RecentToken[]
16
+ availableChainIds: Set<number>
17
+ configTokens: WidgetTokens | undefined
18
+ formType: FormType
19
+ selectedChainId?: number
20
+ isAllNetworks?: boolean
21
+ nativeHoisted: boolean
22
+ disabled: boolean
23
+ }
24
+
25
+ export interface RecentRows {
26
+ /** Unsliced; empty when the band is inactive. */
27
+ rows: TokenAmount[]
28
+ /** Everything Clear removes, including toggled-away and displaced rows. */
29
+ bandEntries: RecentTokenId[]
30
+ recentStartIndex: number
31
+ }
32
+
33
+ export interface RecentTokensResult {
34
+ tokens: TokenAmount[]
35
+ recentCount: number
36
+ totalRecentCount: number
37
+ }
38
+
39
+ // Whitelisted fields; a flag is the one verdict kept, as stale it only over-warns.
40
+ const toSnapshotRow = (recent: RecentToken): TokenAmount =>
41
+ ({
42
+ chainId: recent.chainId,
43
+ address: recent.address,
44
+ symbol: recent.symbol,
45
+ name: recent.name,
46
+ decimals: recent.decimals,
47
+ logoURI: recent.logoURI,
48
+ priceUSD: '',
49
+ verificationStatus: recent.flagged ? 'flagged' : undefined,
50
+ }) as TokenAmount
51
+
52
+ const isFeaturedCopy = (token: TokenAmount): boolean =>
53
+ !!token.featured && !token.amount
54
+
55
+ export const resolveRecentRows = (
56
+ tokens: TokenAmount[],
57
+ {
58
+ recentTokens,
59
+ availableChainIds,
60
+ configTokens,
61
+ formType,
62
+ selectedChainId,
63
+ isAllNetworks,
64
+ nativeHoisted,
65
+ disabled,
66
+ }: ResolveRecentRowsParams
67
+ ): RecentRows => {
68
+ let recentStartIndex = nativeHoisted ? 1 : 0
69
+ while (tokens[recentStartIndex]?.pinned) {
70
+ recentStartIndex++
71
+ }
72
+
73
+ const inactive: RecentRows = { rows: [], bandEntries: [], recentStartIndex }
74
+
75
+ if (disabled || !recentTokens.length || !tokens.length) {
76
+ return inactive
77
+ }
78
+
79
+ const candidates = recentTokens.filter(
80
+ (recent) =>
81
+ (isAllNetworks || recent.chainId === selectedChainId) &&
82
+ availableChainIds.has(recent.chainId)
83
+ )
84
+
85
+ if (!candidates.length) {
86
+ return inactive
87
+ }
88
+
89
+ const wanted = new Set(
90
+ candidates.map((recent) => getTokenKey(recent.chainId, recent.address))
91
+ )
92
+ // All-networks holds tens of thousands of rows: test the chain before the key.
93
+ const wantedChains = new Set(candidates.map((recent) => recent.chainId))
94
+ const fresh = new Map<string, TokenAmount>()
95
+ // A featured config copy has no balance and sits above the row with one.
96
+ let awaitingBalance = 0
97
+ for (const token of tokens) {
98
+ if (!wantedChains.has(token.chainId)) {
99
+ continue
100
+ }
101
+ const key = getTokenKey(token.chainId, token.address)
102
+ if (!wanted.has(key)) {
103
+ continue
104
+ }
105
+ const found = fresh.get(key)
106
+ if (!found) {
107
+ fresh.set(key, token)
108
+ if (isFeaturedCopy(token)) {
109
+ awaitingBalance++
110
+ }
111
+ } else if (token.amount && isFeaturedCopy(found)) {
112
+ fresh.set(key, {
113
+ ...found,
114
+ amount: token.amount,
115
+ priceUSD: token.priceUSD || found.priceUSD,
116
+ })
117
+ awaitingBalance--
118
+ }
119
+ if (fresh.size === wanted.size && !awaitingBalance) {
120
+ break
121
+ }
122
+ }
123
+
124
+ const allowedByChain = new Map<number, AllowDenySets | undefined>()
125
+ const allowedFor = (chainId: number) => {
126
+ if (!allowedByChain.has(chainId)) {
127
+ allowedByChain.set(
128
+ chainId,
129
+ getChainTokenAllowSets(configTokens, chainId, formType)
130
+ )
131
+ }
132
+ return allowedByChain.get(chainId)
133
+ }
134
+
135
+ const hoistedKey = nativeHoisted
136
+ ? getTokenKey(tokens[0].chainId, tokens[0].address)
137
+ : undefined
138
+
139
+ const rows: TokenAmount[] = []
140
+ const bandEntries: RecentTokenId[] = []
141
+ for (const recent of candidates) {
142
+ const key = getTokenKey(recent.chainId, recent.address)
143
+ const resolved = fresh.get(key) ?? toSnapshotRow(recent)
144
+ if (
145
+ !isFormItemAllowed(resolved, allowedFor(recent.chainId), formType, (t) =>
146
+ t.address.toLowerCase()
147
+ )
148
+ ) {
149
+ // Denied on this side only, so Clear must leave it for the other side.
150
+ continue
151
+ }
152
+ // Clear owns displaced entries too, or they reappear once unpinned.
153
+ bandEntries.push({ chainId: recent.chainId, address: recent.address })
154
+ if (key === hoistedKey || resolved.pinned) {
155
+ continue
156
+ }
157
+ rows.push({ ...resolved, recent: true })
158
+ }
159
+
160
+ if (!rows.length) {
161
+ return inactive
162
+ }
163
+
164
+ return { rows, bandEntries, recentStartIndex }
165
+ }
166
+
167
+ export const spliceRecentRows = (
168
+ tokens: TokenAmount[],
169
+ { rows, recentStartIndex }: RecentRows,
170
+ expanded: boolean
171
+ ): RecentTokensResult => {
172
+ if (!rows.length) {
173
+ return { tokens, recentCount: 0, totalRecentCount: 0 }
174
+ }
175
+
176
+ const visible = expanded ? rows : rows.slice(0, collapsedRecentCount)
177
+
178
+ return {
179
+ tokens: [
180
+ ...tokens.slice(0, recentStartIndex),
181
+ ...visible,
182
+ ...tokens.slice(recentStartIndex),
183
+ ],
184
+ recentCount: visible.length,
185
+ totalRecentCount: rows.length,
186
+ }
187
+ }
@@ -1,9 +1,39 @@
1
- import type { BaseToken, RouteExtended, Token, TokenAmount } from '@lifi/sdk'
1
+ import type {
2
+ BaseToken,
3
+ ExtendedChain,
4
+ RouteExtended,
5
+ StaticToken,
6
+ Token,
7
+ TokenAmount,
8
+ TokenExtended,
9
+ } from '@lifi/sdk'
10
+ import { ChainId } from '@lifi/sdk'
2
11
  import type { FormType } from '../stores/form/types.js'
3
- import type { TokensByChain, TokenWithVerified } from '../types/token.js'
4
- import type { WidgetChains, WidgetTokens } from '../types/widget.js'
12
+ import type { TokensByChain, TokenWithFlags } from '../types/token.js'
13
+ import type {
14
+ AllowDenySets,
15
+ WidgetChains,
16
+ WidgetTokens,
17
+ } from '../types/widget.js'
5
18
  import { getConfigItemSets, isFormItemAllowed } from './item.js'
6
19
 
20
+ // Number(): plain-JS integrators may pass chainId as a string.
21
+ export const getChainTokenAllowSets = (
22
+ configTokens: WidgetTokens | undefined,
23
+ chainId: number,
24
+ formType?: FormType
25
+ ): AllowDenySets | undefined =>
26
+ getConfigItemSets(
27
+ configTokens,
28
+ (tokens: BaseToken[]) =>
29
+ new Set(
30
+ tokens
31
+ .filter((t) => Number(t.chainId) === chainId)
32
+ .map((t) => t.address.toLowerCase())
33
+ ),
34
+ formType
35
+ )
36
+
7
37
  /**
8
38
  * Builds per-chain sets of lowercase token addresses from the
9
39
  * `tokens.verified` config allowlist.
@@ -63,9 +93,39 @@ export const mergeVerifiedWithSearchTokens = (
63
93
  return result
64
94
  }
65
95
 
96
+ /**
97
+ * `priceUSD` is a required string, so an unknown price arrives as `'0'` or `''`
98
+ * rather than as an absent key — the same reading as in `useLimitMarketRate`. A
99
+ * known price must never lose to one, or a route that cannot price its output
100
+ * blanks a value the cache already knew.
101
+ */
102
+ export const knownPriceUSD = (fresher: string, cached: string): string =>
103
+ Number(fresher) ? fresher : cached
104
+
105
+ /**
106
+ * Merges a cached token into a route token for display. The route wins on every
107
+ * field it carries; the cache only fills gaps. Letting the cache win instead
108
+ * swaps the quoted price for a stale feed price.
109
+ */
110
+ export const mergeFallbackToken = (
111
+ routeToken: TokenAmount,
112
+ cachedToken: TokenExtended | undefined
113
+ ): TokenAmount =>
114
+ cachedToken
115
+ ? {
116
+ ...cachedToken,
117
+ ...routeToken,
118
+ priceUSD: knownPriceUSD(routeToken.priceUSD, cachedToken.priceUSD),
119
+ logoURI: routeToken.logoURI || cachedToken.logoURI,
120
+ }
121
+ : routeToken
122
+
66
123
  /**
67
124
  * Updates a token in the cache by chainId and address.
68
125
  * Returns a new cache object with the token updated, or the original if not found.
126
+ * Addresses are compared case-insensitively: the token list and the route can
127
+ * spell the same address differently. The incoming token only overwrites what it
128
+ * actually knows, so an unpriced or logo-less route cannot blank the cache.
69
129
  */
70
130
  export const updateTokenInCache = (
71
131
  data: TokensByChain | undefined,
@@ -78,14 +138,26 @@ export const updateTokenInCache = (
78
138
  if (!chainTokens) {
79
139
  return data
80
140
  }
81
- const index = chainTokens.findIndex((t) => t.address === token.address)
141
+ const address = token.address.toLowerCase()
142
+ const index = chainTokens.findIndex(
143
+ (t) => t.address.toLowerCase() === address
144
+ )
82
145
  if (index < 0) {
83
146
  return data
84
147
  }
85
148
  return {
86
149
  ...data,
87
150
  [token.chainId]: chainTokens.map((t, i) =>
88
- i === index ? { ...t, ...token } : t
151
+ i === index
152
+ ? {
153
+ ...t,
154
+ ...token,
155
+ // Keep the cached address: other readers hold it as the identity.
156
+ address: t.address,
157
+ priceUSD: knownPriceUSD(token.priceUSD, t.priceUSD),
158
+ logoURI: token.logoURI || t.logoURI,
159
+ }
160
+ : t
89
161
  ),
90
162
  }
91
163
  }
@@ -94,7 +166,8 @@ export const filterAllowedTokens = (
94
166
  dataTokens: TokensByChain | undefined,
95
167
  configTokens?: WidgetTokens,
96
168
  chainsConfig?: WidgetChains,
97
- formType?: FormType
169
+ formType?: FormType,
170
+ nativeTokenAddresses?: Map<number, string>
98
171
  ): TokensByChain | undefined => {
99
172
  if (!dataTokens) {
100
173
  return
@@ -131,25 +204,21 @@ export const filterAllowedTokens = (
131
204
  chainIncludedTokens.map((t) => t.address.toLowerCase())
132
205
  )
133
206
 
134
- const allowedAddresses = getConfigItemSets(
207
+ const allowedAddresses = getChainTokenAllowSets(
135
208
  configTokens,
136
- (tokens: BaseToken[]) =>
137
- new Set(
138
- tokens
139
- .filter((t) => Number(t.chainId) === chainId)
140
- .map((t) => t.address.toLowerCase())
141
- ),
209
+ chainId,
142
210
  formType
143
211
  )
144
212
 
145
213
  const verifiedAddresses = verifiedTokensSets?.get(chainId)
214
+ const nativeAddress = nativeTokenAddresses?.get(chainId)?.toLowerCase()
146
215
 
147
- const chainTokens: TokenWithVerified[] = [
216
+ const chainTokens: TokenWithFlags[] = [
148
217
  ...(dataTokens[chainId] ?? []),
149
218
  ...chainIncludedTokens,
150
219
  ]
151
220
 
152
- const filtered: TokenWithVerified[] = []
221
+ const filtered: TokenWithFlags[] = []
153
222
  const seenAddresses = new Set<string>()
154
223
  for (const token of chainTokens) {
155
224
  const address = token.address.toLowerCase()
@@ -167,12 +236,18 @@ export const filterAllowedTokens = (
167
236
  continue
168
237
  }
169
238
  // Include and verified-allowlist tokens are explicitly set by the
170
- // integrator, mark them as verified
171
- if (
239
+ // integrator, mark them as verified. Flags are only ever set to true,
240
+ // so a token that earns none keeps its cached object.
241
+ const markVerified =
172
242
  !token.verified &&
173
243
  (includedAddresses.has(address) || verifiedAddresses?.has(address))
174
- ) {
175
- filtered.push({ ...token, verified: true })
244
+ const markNative = !!nativeAddress && nativeAddress === address
245
+ if (markVerified || markNative) {
246
+ filtered.push({
247
+ ...token,
248
+ ...(markVerified ? { verified: true } : {}),
249
+ ...(markNative ? { native: true } : {}),
250
+ })
176
251
  } else {
177
252
  filtered.push(token)
178
253
  }
@@ -192,3 +267,31 @@ export const getExecutionToToken = (route: RouteExtended): TokenAmount => ({
192
267
  route.toAmount
193
268
  ),
194
269
  })
270
+
271
+ /** Capitalized name of the first provider that verified the token. */
272
+ export const getTokenVerificationProvider = (
273
+ token: Pick<StaticToken, 'verificationStatusBreakdown'>
274
+ ): string | undefined => {
275
+ const provider = token.verificationStatusBreakdown?.find(
276
+ (entry) => entry.result === 'verified'
277
+ )?.provider
278
+ return provider
279
+ ? `${provider.charAt(0).toUpperCase()}${provider.slice(1)}`
280
+ : undefined
281
+ }
282
+
283
+ /**
284
+ * Hyperliquid declares Arbitrum USDC as its native token, Lighter declares
285
+ * Ethereum USDC. Neither is a gas token you hold there. A chain-local
286
+ * stablecoin gas token, as on Arc or Stable, is genuine and stays.
287
+ */
288
+ const chainIdsWithoutNativeToken = new Set([ChainId.HPL, ChainId.LTR])
289
+
290
+ export const getNativeTokenAddresses = (
291
+ chains?: ExtendedChain[]
292
+ ): Map<number, string> =>
293
+ new Map(
294
+ chains
295
+ ?.filter((chain) => !chainIdsWithoutNativeToken.has(chain.id))
296
+ .map((chain) => [chain.id, chain.nativeToken.address])
297
+ )