@lifi/widget 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/dist/esm/App.js.map +1 -1
  2. package/dist/esm/AppDrawer.js +2 -1
  3. package/dist/esm/AppDrawer.js.map +1 -1
  4. package/dist/esm/AppLayout.js.map +1 -1
  5. package/dist/esm/AppProvider.js.map +1 -1
  6. package/dist/esm/components/ActionRow/ActionRow.js.map +1 -1
  7. package/dist/esm/components/AmountInput/AmountInput.js +13 -7
  8. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  9. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +2 -13
  10. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  11. package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
  12. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
  13. package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -1
  14. package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -1
  15. package/dist/esm/components/AmountInputCard/PercentageChips.js +2 -13
  16. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -1
  17. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +1 -1
  18. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -1
  19. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
  20. package/dist/esm/components/AmountInputCard/SendAmountCard.js +13 -6
  21. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -1
  22. package/dist/esm/components/AppContainer.js.map +1 -1
  23. package/dist/esm/components/Avatar/AccountAvatar.js.map +1 -1
  24. package/dist/esm/components/Avatar/Avatar.js.map +1 -1
  25. package/dist/esm/components/Avatar/ChainBadgeContent.js.map +1 -1
  26. package/dist/esm/components/Avatar/TokenAvatar.js.map +1 -1
  27. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
  28. package/dist/esm/components/Card/CardButton.js.map +1 -1
  29. package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
  30. package/dist/esm/components/Chains/AllChainsAvatar.js +7 -1
  31. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
  32. package/dist/esm/components/Chains/ChainList.js.map +1 -1
  33. package/dist/esm/components/Chains/ChainListItem.js.map +1 -1
  34. package/dist/esm/components/Chains/ChainsExpanded.js.map +1 -1
  35. package/dist/esm/components/Chains/PinChainButton.js.map +1 -1
  36. package/dist/esm/components/Chains/SelectChainExpansionContent.js.map +1 -1
  37. package/dist/esm/components/Chains/SelectChainPageContent.js.map +1 -1
  38. package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
  39. package/dist/esm/components/ContextMenu.js.map +1 -1
  40. package/dist/esm/components/ContractComponent/NFT/NFTBase.js.map +1 -1
  41. package/dist/esm/components/Dialog/Dialog.js +2 -1
  42. package/dist/esm/components/Dialog/Dialog.js.map +1 -1
  43. package/dist/esm/components/ExecutionStatusCard/ExecutionChecklist.js.map +1 -1
  44. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.js.map +1 -1
  45. package/dist/esm/components/ExecutionStatusCard/StaggeredRevealTypography.js.map +1 -1
  46. package/dist/esm/components/ExecutionStatusCard/StatusIcon.js.map +1 -1
  47. package/dist/esm/components/Expansion/Expansion.js +4 -3
  48. package/dist/esm/components/Expansion/Expansion.js.map +1 -1
  49. package/dist/esm/components/Expansion/ExpansionTransition.js.map +1 -1
  50. package/dist/esm/components/FeeBreakdownTooltip.js.map +1 -1
  51. package/dist/esm/components/Header/ActivitiesButton.js.map +1 -1
  52. package/dist/esm/components/Header/BackButton.js.map +1 -1
  53. package/dist/esm/components/Header/CloseDrawerButton.js.map +1 -1
  54. package/dist/esm/components/Header/DisconnectIconButton.js.map +1 -1
  55. package/dist/esm/components/Header/HeaderTabs.js.map +1 -1
  56. package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
  57. package/dist/esm/components/Header/SettingsButton.js +2 -1
  58. package/dist/esm/components/Header/SettingsButton.js.map +1 -1
  59. package/dist/esm/components/Header/WalletHeader.js.map +1 -1
  60. package/dist/esm/components/Header/WalletMenu.js.map +1 -1
  61. package/dist/esm/components/IconCircle/IconCircle.js +2 -1
  62. package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
  63. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -1
  64. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -1
  65. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -1
  66. package/dist/esm/components/Messages/AccountDeployedMessage.js.map +1 -1
  67. package/dist/esm/components/Messages/AccountNotDeployedMessage.js.map +1 -1
  68. package/dist/esm/components/Messages/AlertMessage.js.map +1 -1
  69. package/dist/esm/components/Messages/FundsSufficiencyMessage.js.map +1 -1
  70. package/dist/esm/components/Messages/GasRefuelMessage.js.map +1 -1
  71. package/dist/esm/components/Messages/GasSufficiencyMessage.js.map +1 -1
  72. package/dist/esm/components/Messages/MinFromAmountUSDMessage.js.map +1 -1
  73. package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.js.map +1 -1
  74. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js +27 -0
  75. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js.map +1 -0
  76. package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
  77. package/dist/esm/components/Messages/WarningMessages.js +2 -0
  78. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  79. package/dist/esm/components/Messages/useMessageQueue.js +6 -1
  80. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  81. package/dist/esm/components/NotFound.js.map +1 -1
  82. package/dist/esm/components/PoweredBy/PoweredBy.js.map +1 -1
  83. package/dist/esm/components/ProgressToNextUpdate.js.map +1 -1
  84. package/dist/esm/components/ReverseTokensButton/ReverseTokensButton.js.map +1 -1
  85. package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
  86. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  87. package/dist/esm/components/RouteCard/RouteCardSkeleton.js.map +1 -1
  88. package/dist/esm/components/RouteCard/RouteDetails.js +2 -1
  89. package/dist/esm/components/RouteCard/RouteDetails.js.map +1 -1
  90. package/dist/esm/components/RouteCard/RouteNotFoundCard.js.map +1 -1
  91. package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -1
  92. package/dist/esm/components/RouteCard/RouteToken.js.map +1 -1
  93. package/dist/esm/components/RouteCard/RouteTokens.js.map +1 -1
  94. package/dist/esm/components/Routes/LimitOrderRoutes.js +2 -2
  95. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -1
  96. package/dist/esm/components/Routes/Routes.js.map +1 -1
  97. package/dist/esm/components/Routes/RoutesContent.js +2 -2
  98. package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
  99. package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
  100. package/dist/esm/components/Search/SearchInput.js.map +1 -1
  101. package/dist/esm/components/SelectChainAndToken.js.map +1 -1
  102. package/dist/esm/components/SelectTokenButton/SelectTokenButton.js.map +1 -1
  103. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  104. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +2 -2
  105. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  106. package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -1
  107. package/dist/esm/components/Skeleton/WidgetSkeleton.js +2 -1
  108. package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
  109. package/dist/esm/components/Step/StepActions.js +18 -16
  110. package/dist/esm/components/Step/StepActions.js.map +1 -1
  111. package/dist/esm/components/StepActions/SentToWalletRow.js.map +1 -1
  112. package/dist/esm/components/StepActions/StepActionRow.js +2 -1
  113. package/dist/esm/components/StepActions/StepActionRow.js.map +1 -1
  114. package/dist/esm/components/StepActions/StepActionsList.js.map +1 -1
  115. package/dist/esm/components/SwapButton/SwapButton.js.map +1 -1
  116. package/dist/esm/components/Switch.js +1 -1
  117. package/dist/esm/components/Switch.js.map +1 -1
  118. package/dist/esm/components/Tabs/Tabs.style.js +4 -2
  119. package/dist/esm/components/Tabs/Tabs.style.js.map +1 -1
  120. package/dist/esm/components/TextFitter/TextFitter.js.map +1 -1
  121. package/dist/esm/components/Timer/StepStatusTimer.js.map +1 -1
  122. package/dist/esm/components/Token/Token.js.map +1 -1
  123. package/dist/esm/components/TokenList/PinTokenButton.js.map +1 -1
  124. package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
  125. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
  126. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  127. package/dist/esm/components/TokenList/TokenListItem.js +46 -8
  128. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  129. package/dist/esm/components/TokenList/VirtualizedTokenList.js +22 -9
  130. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  131. package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -1
  132. package/dist/esm/components/TokenRate/TokenRate.js +2 -1
  133. package/dist/esm/components/TokenRate/TokenRate.js.map +1 -1
  134. package/dist/esm/components/Tools/ToolItem.js.map +1 -1
  135. package/dist/esm/components/Tools/Tools.js.map +1 -1
  136. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +22 -21
  137. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
  138. package/dist/esm/components/TransactionCard/TransactionCard.js.map +1 -1
  139. package/dist/esm/components/TransactionCard/TransactionCardSkeleton.js.map +1 -1
  140. package/dist/esm/config/version.d.ts +1 -1
  141. package/dist/esm/config/version.js +1 -1
  142. package/dist/esm/config/version.js.map +1 -1
  143. package/dist/esm/hooks/timer/time.js +2 -2
  144. package/dist/esm/hooks/timer/time.js.map +1 -1
  145. package/dist/esm/hooks/useAccountsBalancesData.js +1 -14
  146. package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
  147. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  148. package/dist/esm/hooks/useAvailableChains.js +2 -1
  149. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  150. package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
  151. package/dist/esm/hooks/useExplorer.js +4 -0
  152. package/dist/esm/hooks/useExplorer.js.map +1 -1
  153. package/dist/esm/hooks/useFlaggedTokenGuard.js +28 -0
  154. package/dist/esm/hooks/useFlaggedTokenGuard.js.map +1 -0
  155. package/dist/esm/hooks/useGasSufficiency.js +3 -1
  156. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  157. package/dist/esm/hooks/useMaxSendAmount.js +15 -0
  158. package/dist/esm/hooks/useMaxSendAmount.js.map +1 -0
  159. package/dist/esm/hooks/usePacedRouteExecution.js +3 -2
  160. package/dist/esm/hooks/usePacedRouteExecution.js.map +1 -1
  161. package/dist/esm/hooks/useRouteExecutionMessage.js +3 -2
  162. package/dist/esm/hooks/useRouteExecutionMessage.js.map +1 -1
  163. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  164. package/dist/esm/hooks/useRoutes.js +3 -1
  165. package/dist/esm/hooks/useRoutes.js.map +1 -1
  166. package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
  167. package/dist/esm/hooks/useToAddressRequirements.d.ts +2 -0
  168. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  169. package/dist/esm/hooks/useToAddressRequirements.js +7 -1
  170. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  171. package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
  172. package/dist/esm/hooks/useTokenBalances.js +7 -2
  173. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  174. package/dist/esm/hooks/useTokenBalancesQueries.js +32 -29
  175. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
  176. package/dist/esm/hooks/useTokenSearch.js +3 -5
  177. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  178. package/dist/esm/hooks/useTokens.js +14 -10
  179. package/dist/esm/hooks/useTokens.js.map +1 -1
  180. package/dist/esm/hooks/useWideVariant.js +2 -1
  181. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  182. package/dist/esm/i18n/bn.json +3 -1
  183. package/dist/esm/i18n/de.json +3 -1
  184. package/dist/esm/i18n/en.json +12 -3
  185. package/dist/esm/i18n/es.json +3 -1
  186. package/dist/esm/i18n/fr.json +3 -1
  187. package/dist/esm/i18n/hi.json +3 -1
  188. package/dist/esm/i18n/id.json +3 -1
  189. package/dist/esm/i18n/it.json +3 -1
  190. package/dist/esm/i18n/ja.json +3 -1
  191. package/dist/esm/i18n/ko.json +3 -1
  192. package/dist/esm/i18n/pl.json +3 -1
  193. package/dist/esm/i18n/pt.json +3 -1
  194. package/dist/esm/i18n/th.json +3 -1
  195. package/dist/esm/i18n/tr.json +3 -1
  196. package/dist/esm/i18n/uk.json +3 -1
  197. package/dist/esm/i18n/vi.json +3 -1
  198. package/dist/esm/i18n/zh.json +3 -1
  199. package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js.map +1 -1
  200. package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js.map +1 -1
  201. package/dist/esm/pages/LanguagesPage.js.map +1 -1
  202. package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -1
  203. package/dist/esm/pages/MainPage/MainPage.js +2 -1
  204. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  205. package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -1
  206. package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
  207. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  208. package/dist/esm/pages/RoutePriorityPage.js.map +1 -1
  209. package/dist/esm/pages/RoutesPage/RoutesPage.js +2 -2
  210. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  211. package/dist/esm/pages/SelectChainPage/SelectChainPage.js +13 -12
  212. package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  213. package/dist/esm/pages/SelectEnabledToolsPage.js +8 -5
  214. package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
  215. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +2 -1
  216. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  217. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
  218. package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  219. package/dist/esm/pages/SendToWallet/ConfirmAddressSheet.js.map +1 -1
  220. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  221. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  222. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  223. package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  224. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
  225. package/dist/esm/pages/SettingsPage/GasPriceSettings.js.map +1 -1
  226. package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
  227. package/dist/esm/pages/SettingsPage/ResetSettingsButton.js.map +1 -1
  228. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
  229. package/dist/esm/pages/SettingsPage/SettingsCard/BadgedValue.js.map +1 -1
  230. package/dist/esm/pages/SettingsPage/SettingsCard/SettingCardExpandable.js.map +1 -1
  231. package/dist/esm/pages/SettingsPage/SettingsPage.js.map +1 -1
  232. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -1
  233. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
  234. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js +2 -1
  235. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
  236. package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  237. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js +2 -1
  238. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
  239. package/dist/esm/pages/TransactionDetailsPage/ReceiptsCard.js.map +1 -1
  240. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +2 -1
  241. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  242. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsSkeleton.js.map +1 -1
  243. package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -1
  244. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js.map +1 -1
  245. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
  246. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.js.map +1 -1
  247. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +4 -3
  248. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  249. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  250. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +64 -0
  251. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -0
  252. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.js.map +1 -1
  253. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js +19 -16
  254. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js.map +1 -1
  255. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +3 -1
  256. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
  257. package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  258. package/dist/esm/pages/TransactionPage/TransactionReview.js +24 -2
  259. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  260. package/dist/esm/providers/I18nProvider/I18nProvider.js +37 -36
  261. package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  262. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  263. package/dist/esm/providers/ThemeProvider/ThemeProvider.js +2 -1
  264. package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
  265. package/dist/esm/providers/WalletProvider/WalletProvider.js +10 -9
  266. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  267. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
  268. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
  269. package/dist/esm/stores/StoreProvider.js.map +1 -1
  270. package/dist/esm/stores/form/FormStore.js.map +1 -1
  271. package/dist/esm/stores/form/FormUpdater.js.map +1 -1
  272. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
  273. package/dist/esm/stores/routes/useRouteExecutionIndicator.js +4 -3
  274. package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
  275. package/dist/esm/types/token.d.ts +4 -1
  276. package/dist/esm/types/token.d.ts.map +1 -1
  277. package/dist/esm/utils/compactNumberFormatter.js +1 -3
  278. package/dist/esm/utils/compactNumberFormatter.js.map +1 -1
  279. package/dist/esm/utils/customReceiver.js +7 -0
  280. package/dist/esm/utils/customReceiver.js.map +1 -0
  281. package/dist/esm/utils/gas.js +24 -0
  282. package/dist/esm/utils/gas.js.map +1 -0
  283. package/dist/esm/utils/getErrorMessage.js +0 -1
  284. package/dist/esm/utils/getErrorMessage.js.map +1 -1
  285. package/dist/esm/utils/limitOrder.js +1 -1
  286. package/dist/esm/utils/limitOrder.js.map +1 -1
  287. package/dist/esm/utils/token.js +21 -4
  288. package/dist/esm/utils/token.js.map +1 -1
  289. package/dist/esm/utils/tokenList.js +37 -23
  290. package/dist/esm/utils/tokenList.js.map +1 -1
  291. package/package.json +15 -15
  292. package/src/components/AmountInput/AmountInputEndAdornment.tsx +2 -21
  293. package/src/components/AmountInputCard/PercentageChips.tsx +2 -18
  294. package/src/components/Chains/AllChainsAvatar.tsx +7 -1
  295. package/src/components/Messages/UnsupportedToAddressMessage.tsx +24 -0
  296. package/src/components/Messages/WarningMessages.tsx +3 -0
  297. package/src/components/Messages/useMessageQueue.ts +9 -0
  298. package/src/components/Routes/LimitOrderRoutes.tsx +5 -2
  299. package/src/components/Routes/RoutesContent.tsx +5 -2
  300. package/src/components/SendToWallet/SendToWalletExpandButton.tsx +2 -1
  301. package/src/components/TokenList/TokenListItem.tsx +68 -9
  302. package/src/components/TokenList/VirtualizedTokenList.tsx +33 -9
  303. package/src/components/TokenList/types.ts +4 -0
  304. package/src/config/version.ts +1 -1
  305. package/src/hooks/useAccountsBalancesData.ts +4 -31
  306. package/src/hooks/useAvailableChains.ts +1 -0
  307. package/src/hooks/useExplorer.ts +2 -0
  308. package/src/hooks/useFlaggedTokenGuard.ts +33 -0
  309. package/src/hooks/useGasSufficiency.ts +9 -1
  310. package/src/hooks/useMaxSendAmount.ts +21 -0
  311. package/src/hooks/useRoutes.ts +7 -0
  312. package/src/hooks/useToAddressRequirements.ts +17 -1
  313. package/src/hooks/useTokenBalances.ts +18 -2
  314. package/src/hooks/useTokenBalancesQueries.ts +12 -4
  315. package/src/hooks/useTokenSearch.ts +1 -5
  316. package/src/hooks/useTokens.ts +28 -13
  317. package/src/pages/MainPage/ReviewButton.tsx +6 -2
  318. package/src/pages/RoutesPage/RoutesPage.tsx +5 -2
  319. package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +93 -0
  320. package/src/pages/TransactionPage/TransactionReview.tsx +28 -1
  321. package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
  322. package/src/types/token.ts +6 -3
  323. package/src/utils/customReceiver.ts +7 -0
  324. package/src/utils/gas.ts +41 -0
  325. package/src/utils/token.ts +53 -9
  326. package/src/utils/tokenList.ts +27 -7
  327. package/dist/esm/hooks/useFilteredByTokenBalances.js +0 -74
  328. package/dist/esm/hooks/useFilteredByTokenBalances.js.map +0 -1
  329. package/src/hooks/useFilteredByTokenBalances.ts +0 -145
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionCard.js","names":["Card"],"sources":["../../../../src/components/TransactionCard/TransactionCard.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { Box } from '@mui/material'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { Card } from '../Card/Card.js'\nimport { RouteTokens } from '../RouteCard/RouteTokens.js'\nimport { DateLabelContainer, DateLabelText } from './TransactionCard.style.js'\n\ninterface TransactionCardProps {\n route: RouteExtended\n date: Date\n onClick?: () => void\n}\n\nexport const TransactionCard = ({\n route,\n date,\n onClick,\n}: TransactionCardProps): JSX.Element => {\n const { i18n } = useTranslation()\n\n return (\n <Card indented onClick={onClick}>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <DateLabelContainer>\n <DateLabelText color=\"text.secondary\">\n {date.toLocaleString(i18n.language, { dateStyle: 'long' })}\n </DateLabelText>\n <DateLabelText color=\"text.secondary\">\n {date.toLocaleString(i18n.language, { timeStyle: 'short' })}\n </DateLabelText>\n </DateLabelContainer>\n <RouteTokens route={route} />\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;AAcA,MAAa,mBAAmB,EAC9B,OACA,MACA,cACuC;CACvC,MAAM,EAAE,SAAS,eAAe;CAEhC,OACE,oBAACA,QAAD;EAAM,UAAA;EAAkB;YACtB,qBAAC,KAAD;GAAK,IAAI;IAAE,SAAS;IAAQ,eAAe;IAAU,KAAK;GAAI;aAA9D,CACE,qBAAC,oBAAD,EAAA,UAAA,CACE,oBAAC,eAAD;IAAe,OAAM;cAClB,KAAK,eAAe,KAAK,UAAU,EAAE,WAAW,OAAO,CAAC;GAC5C,CAAA,GACf,oBAAC,eAAD;IAAe,OAAM;cAClB,KAAK,eAAe,KAAK,UAAU,EAAE,WAAW,QAAQ,CAAC;GAC7C,CAAA,CACG,EAAA,CAAA,GACpB,oBAAC,aAAD,EAAoB,MAAQ,CAAA,CACzB;;CACD,CAAA;AAEV"}
1
+ {"version":3,"file":"TransactionCard.js","names":["Card"],"sources":["../../../../src/components/TransactionCard/TransactionCard.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { Box } from '@mui/material'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { Card } from '../Card/Card.js'\nimport { RouteTokens } from '../RouteCard/RouteTokens.js'\nimport { DateLabelContainer, DateLabelText } from './TransactionCard.style.js'\n\ninterface TransactionCardProps {\n route: RouteExtended\n date: Date\n onClick?: () => void\n}\n\nexport const TransactionCard = ({\n route,\n date,\n onClick,\n}: TransactionCardProps): JSX.Element => {\n const { i18n } = useTranslation()\n\n return (\n <Card indented onClick={onClick}>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <DateLabelContainer>\n <DateLabelText color=\"text.secondary\">\n {date.toLocaleString(i18n.language, { dateStyle: 'long' })}\n </DateLabelText>\n <DateLabelText color=\"text.secondary\">\n {date.toLocaleString(i18n.language, { timeStyle: 'short' })}\n </DateLabelText>\n </DateLabelContainer>\n <RouteTokens route={route} />\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;AAcA,MAAa,mBAAmB,EAC9B,OACA,MACA,cACuC;CACvC,MAAM,EAAE,SAAS,eAAe;CAEhC,OACE,oBAACA,QAAD;EAAM,UAAA;EAAkB;EACtB,UAAA,qBAAC,KAAD;GAAK,IAAI;IAAE,SAAS;IAAQ,eAAe;IAAU,KAAK;GAAI;GAA9D,UAAA,CACE,qBAAC,oBAAD,EAAA,UAAA,CACE,oBAAC,eAAD;IAAe,OAAM;IAClB,UAAA,KAAK,eAAe,KAAK,UAAU,EAAE,WAAW,OAAO,CAAC;GAC5C,CAAA,GACf,oBAAC,eAAD;IAAe,OAAM;IAClB,UAAA,KAAK,eAAe,KAAK,UAAU,EAAE,WAAW,QAAQ,CAAC;GAC7C,CAAA,CACG,EAAA,CAAA,GACpB,oBAAC,aAAD,EAAoB,MAAQ,CAAA,CACzB;;CACD,CAAA;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionCardSkeleton.js","names":["Card"],"sources":["../../../../src/components/TransactionCard/TransactionCardSkeleton.tsx"],"sourcesContent":["import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'\nimport { Box, Skeleton } from '@mui/material'\nimport type { JSX } from 'react'\nimport { Card } from '../Card/Card.js'\nimport { TokenSkeleton } from '../Token/Token.js'\n\ninterface TransactionCardSkeletonProps {\n active?: boolean\n}\n\nexport const TransactionCardSkeleton = ({\n active,\n}: TransactionCardSkeletonProps): JSX.Element => {\n return (\n <Card indented>\n {active ? (\n <Skeleton\n variant=\"rectangular\"\n height={40}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadiusTertiary,\n mb: 1.5,\n })}\n />\n ) : (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n pb: 1.5,\n }}\n >\n <Skeleton\n variant=\"rectangular\"\n width={96}\n height={18}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadius,\n })}\n />\n <Skeleton\n variant=\"rectangular\"\n width={64}\n height={18}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadius,\n })}\n />\n </Box>\n )}\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <TokenSkeleton />\n <Box\n sx={{\n width: 40,\n height: 20,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <ArrowDownwardIcon sx={{ fontSize: 16, color: 'text.secondary' }} />\n </Box>\n <TokenSkeleton />\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;AAUA,MAAa,2BAA2B,EACtC,aAC+C;CAC/C,OACE,qBAACA,QAAD;EAAM,UAAA;YAAN,CACG,SACC,oBAAC,UAAD;GACE,SAAQ;GACR,QAAQ;GACR,KAAK,WAAW;IACd,cAAc,MAAM,KAAK,MAAM;IAC/B,IAAI;GACN;EACD,CAAA,IAED,qBAAC,KAAD;GACE,IAAI;IACF,SAAS;IACT,gBAAgB;IAChB,IAAI;GACN;aALF,CAOE,oBAAC,UAAD;IACE,SAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK,WAAW,EACd,cAAc,MAAM,KAAK,MAAM,aACjC;GACD,CAAA,GACD,oBAAC,UAAD;IACE,SAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK,WAAW,EACd,cAAc,MAAM,KAAK,MAAM,aACjC;GACD,CAAA,CACE;MAEP,qBAAC,KAAD;GAAK,IAAI;IAAE,SAAS;IAAQ,eAAe;IAAU,KAAK;GAAI;aAA9D;IACE,oBAAC,eAAD,CAAgB,CAAA;IAChB,oBAAC,KAAD;KACE,IAAI;MACF,OAAO;MACP,QAAQ;MACR,SAAS;MACT,YAAY;MACZ,gBAAgB;KAClB;eAEA,oBAAC,mBAAD,EAAmB,IAAI;MAAE,UAAU;MAAI,OAAO;KAAiB,EAAI,CAAA;IAChE,CAAA;IACL,oBAAC,eAAD,CAAgB,CAAA;GACb;IACD;;AAEV"}
1
+ {"version":3,"file":"TransactionCardSkeleton.js","names":["Card"],"sources":["../../../../src/components/TransactionCard/TransactionCardSkeleton.tsx"],"sourcesContent":["import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'\nimport { Box, Skeleton } from '@mui/material'\nimport type { JSX } from 'react'\nimport { Card } from '../Card/Card.js'\nimport { TokenSkeleton } from '../Token/Token.js'\n\ninterface TransactionCardSkeletonProps {\n active?: boolean\n}\n\nexport const TransactionCardSkeleton = ({\n active,\n}: TransactionCardSkeletonProps): JSX.Element => {\n return (\n <Card indented>\n {active ? (\n <Skeleton\n variant=\"rectangular\"\n height={40}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadiusTertiary,\n mb: 1.5,\n })}\n />\n ) : (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n pb: 1.5,\n }}\n >\n <Skeleton\n variant=\"rectangular\"\n width={96}\n height={18}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadius,\n })}\n />\n <Skeleton\n variant=\"rectangular\"\n width={64}\n height={18}\n sx={(theme) => ({\n borderRadius: theme.vars.shape.borderRadius,\n })}\n />\n </Box>\n )}\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>\n <TokenSkeleton />\n <Box\n sx={{\n width: 40,\n height: 20,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <ArrowDownwardIcon sx={{ fontSize: 16, color: 'text.secondary' }} />\n </Box>\n <TokenSkeleton />\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;AAUA,MAAa,2BAA2B,EACtC,aAC+C;CAC/C,OACE,qBAACA,QAAD;EAAM,UAAA;EAAN,UAAA,CACG,SACC,oBAAC,UAAD;GACE,SAAQ;GACR,QAAQ;GACR,KAAK,WAAW;IACd,cAAc,MAAM,KAAK,MAAM;IAC/B,IAAI;GACN;EACD,CAAA,IAED,qBAAC,KAAD;GACE,IAAI;IACF,SAAS;IACT,gBAAgB;IAChB,IAAI;GACN;GALF,UAAA,CAOE,oBAAC,UAAD;IACE,SAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK,WAAW,EACd,cAAc,MAAM,KAAK,MAAM,aACjC;GACD,CAAA,GACD,oBAAC,UAAD;IACE,SAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK,WAAW,EACd,cAAc,MAAM,KAAK,MAAM,aACjC;GACD,CAAA,CACE;EAEP,CAAA,GAAA,qBAAC,KAAD;GAAK,IAAI;IAAE,SAAS;IAAQ,eAAe;IAAU,KAAK;GAAI;GAA9D,UAAA;IACE,oBAAC,eAAD,CAAgB,CAAA;IAChB,oBAAC,KAAD;KACE,IAAI;MACF,OAAO;MACP,QAAQ;MACR,SAAS;MACT,YAAY;MACZ,gBAAgB;KAClB;KAEA,UAAA,oBAAC,mBAAD,EAAmB,IAAI;MAAE,UAAU;MAAI,OAAO;KAAiB,EAAI,CAAA;IAChE,CAAA;IACL,oBAAC,eAAD,CAAgB,CAAA;GACb;EACD,CAAA,CAAA;;AAEV"}
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.d.ts
2
2
  declare const name = "@lifi/widget";
3
- declare const version = "4.4.0";
3
+ declare const version = "4.6.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.ts
2
2
  const name = "@lifi/widget";
3
- const version = "4.4.0";
3
+ const version = "4.6.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.4.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.6.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
@@ -1,8 +1,8 @@
1
1
  //#region src/hooks/timer/time.ts
2
2
  function getTimeFromMilliseconds(millisecs, isCountDown = true) {
3
3
  const totalSeconds = isCountDown ? Math.ceil(millisecs / 1e3) : Math.floor(millisecs / 1e3);
4
- const days = Math.floor(totalSeconds / (3600 * 24));
5
- const hours = Math.floor(totalSeconds % (3600 * 24) / 3600);
4
+ const days = Math.floor(totalSeconds / 86400);
5
+ const hours = Math.floor(totalSeconds % 86400 / 3600);
6
6
  const minutes = Math.floor(totalSeconds % 3600 / 60);
7
7
  const seconds = Math.floor(totalSeconds % 60);
8
8
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","names":[],"sources":["../../../../src/hooks/timer/time.ts"],"sourcesContent":["export type TimeFromMillisecondsType = {\n totalMilliseconds: number\n totalSeconds: number\n milliseconds: number\n seconds: number\n minutes: number\n hours: number\n days: number\n}\n\nexport function getTimeFromMilliseconds(\n millisecs: number,\n isCountDown = true\n): TimeFromMillisecondsType {\n const totalSeconds = isCountDown\n ? Math.ceil(millisecs / 1000)\n : Math.floor(millisecs / 1000)\n const days = Math.floor(totalSeconds / (60 * 60 * 24))\n const hours = Math.floor((totalSeconds % (60 * 60 * 24)) / (60 * 60))\n const minutes = Math.floor((totalSeconds % (60 * 60)) / 60)\n const seconds = Math.floor(totalSeconds % 60)\n const milliseconds = Math.floor(millisecs % 1000)\n\n return {\n totalMilliseconds: millisecs,\n totalSeconds,\n milliseconds,\n seconds,\n minutes,\n hours,\n days,\n }\n}\n\nexport function getMillisecondsFromExpiry(expiry: Date): number {\n const now = Date.now()\n const milliSecondsDistance = expiry?.getTime() - now\n return milliSecondsDistance > 0 ? milliSecondsDistance : 0\n}\n"],"mappings":";AAUA,SAAgB,wBACd,WACA,cAAc,MACY;CAC1B,MAAM,eAAe,cACjB,KAAK,KAAK,YAAY,GAAI,IAC1B,KAAK,MAAM,YAAY,GAAI;CAC/B,MAAM,OAAO,KAAK,MAAM,gBAAgB,OAAU,GAAG;CACrD,MAAM,QAAQ,KAAK,MAAO,gBAAgB,OAAU,MAAQ,IAAQ;CACpE,MAAM,UAAU,KAAK,MAAO,eAAgB,OAAY,EAAE;CAC1D,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAG5C,OAAO;EACL,mBAAmB;EACnB;EACA,cALmB,KAAK,MAAM,YAAY,GAK/B;EACX;EACA;EACA;EACA;CACF;AACF;AAEA,SAAgB,0BAA0B,QAAsB;CAC9D,MAAM,MAAM,KAAK,IAAI;CACrB,MAAM,uBAAuB,QAAQ,QAAQ,IAAI;CACjD,OAAO,uBAAuB,IAAI,uBAAuB;AAC3D"}
1
+ {"version":3,"file":"time.js","names":[],"sources":["../../../../src/hooks/timer/time.ts"],"sourcesContent":["export type TimeFromMillisecondsType = {\n totalMilliseconds: number\n totalSeconds: number\n milliseconds: number\n seconds: number\n minutes: number\n hours: number\n days: number\n}\n\nexport function getTimeFromMilliseconds(\n millisecs: number,\n isCountDown = true\n): TimeFromMillisecondsType {\n const totalSeconds = isCountDown\n ? Math.ceil(millisecs / 1000)\n : Math.floor(millisecs / 1000)\n const days = Math.floor(totalSeconds / (60 * 60 * 24))\n const hours = Math.floor((totalSeconds % (60 * 60 * 24)) / (60 * 60))\n const minutes = Math.floor((totalSeconds % (60 * 60)) / 60)\n const seconds = Math.floor(totalSeconds % 60)\n const milliseconds = Math.floor(millisecs % 1000)\n\n return {\n totalMilliseconds: millisecs,\n totalSeconds,\n milliseconds,\n seconds,\n minutes,\n hours,\n days,\n }\n}\n\nexport function getMillisecondsFromExpiry(expiry: Date): number {\n const now = Date.now()\n const milliSecondsDistance = expiry?.getTime() - now\n return milliSecondsDistance > 0 ? milliSecondsDistance : 0\n}\n"],"mappings":";AAUA,SAAgB,wBACd,WACA,cAAc,MACY;CAC1B,MAAM,eAAe,cACjB,KAAK,KAAK,YAAY,GAAI,IAC1B,KAAK,MAAM,YAAY,GAAI;CAC/B,MAAM,OAAO,KAAK,MAAM,eAAgB,KAAa;CACrD,MAAM,QAAQ,KAAK,MAAO,eAAgB,QAAkB,IAAQ;CACpE,MAAM,UAAU,KAAK,MAAO,eAAgB,OAAY,EAAE;CAC1D,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAG5C,OAAO;EACL,mBAAmB;EACnB;EACA,cALmB,KAAK,MAAM,YAAY,GAK/B;EACX;EACA;EACA;EACA;CACF;AACF;AAEA,SAAgB,0BAA0B,QAAsB;CAC9D,MAAM,MAAM,KAAK,IAAI;CACrB,MAAM,uBAAuB,QAAQ,QAAQ,IAAI;CACjD,OAAO,uBAAuB,IAAI,uBAAuB;AAC3D"}
@@ -1,17 +1,8 @@
1
1
  import { useChains } from "./useChains.js";
2
- import { useFilteredTokensByBalance } from "./useFilteredByTokenBalances.js";
3
2
  import { useMemo } from "react";
4
3
  import { useAccount } from "@lifi/wallet-management";
5
4
  //#region src/hooks/useAccountsBalancesData.ts
6
5
  const useAccountsBalancesData = (selectedChainId, formType, isAllNetworks, allTokens) => {
7
- const { data: accountsWithTokens, isLoading: isAccountsLoading } = useAccountsData(selectedChainId, formType, isAllNetworks, allTokens);
8
- const { data: filteredTokens, isLoading: isCachedBalancesLoading } = useFilteredTokensByBalance(accountsWithTokens, formType);
9
- return {
10
- data: filteredTokens,
11
- isLoading: isAccountsLoading || isCachedBalancesLoading
12
- };
13
- };
14
- const useAccountsData = (selectedChainId, formType, isAllNetworks, allTokens) => {
15
6
  const { chains: allChains, isLoading: isChainsLoading, getChainById } = useChains(formType);
16
7
  const currentChain = useMemo(() => {
17
8
  return selectedChainId ? getChainById(selectedChainId, allChains) : void 0;
@@ -43,15 +34,11 @@ const useAccountsData = (selectedChainId, formType, isAllNetworks, allTokens) =>
43
34
  const accountChains = chains?.filter((chain) => account.chainType === chain?.chainType);
44
35
  if (accountChains) {
45
36
  const chainIdSet = new Set(accountChains.map((chain) => chain.id));
46
- const filteredTokens = Object.entries(allTokens).reduce((tokenAcc, [chainIdStr, tokens]) => {
37
+ acc[account.address] = Object.entries(allTokens).reduce((tokenAcc, [chainIdStr, tokens]) => {
47
38
  const chainId = Number(chainIdStr);
48
39
  if (chainIdSet.has(chainId)) tokenAcc[chainId] = tokens;
49
40
  return tokenAcc;
50
41
  }, {});
51
- acc[account.address] = {
52
- chainType: account.chainType,
53
- tokens: filteredTokens
54
- };
55
42
  }
56
43
  }
57
44
  return acc;
@@ -1 +1 @@
1
- {"version":3,"file":"useAccountsBalancesData.js","names":[],"sources":["../../../src/hooks/useAccountsBalancesData.ts"],"sourcesContent":["import type { ChainType, TokenExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport type { FormType } from '../stores/form/types.js'\nimport { useChains } from './useChains.js'\nimport { useFilteredTokensByBalance } from './useFilteredByTokenBalances.js'\n\nexport const useAccountsBalancesData = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n allTokens?: Record<number, TokenExtended[]>\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const { data: accountsWithTokens, isLoading: isAccountsLoading } =\n useAccountsData(selectedChainId, formType, isAllNetworks, allTokens)\n\n // Filter out EVM tokens that do not have balances\n const { data: filteredTokens, isLoading: isCachedBalancesLoading } =\n useFilteredTokensByBalance(accountsWithTokens, formType)\n\n return {\n data: filteredTokens,\n isLoading: isAccountsLoading || isCachedBalancesLoading,\n }\n}\n\nconst useAccountsData = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n allTokens?: Record<number, TokenExtended[]>\n) => {\n const {\n chains: allChains,\n isLoading: isChainsLoading,\n getChainById,\n } = useChains(formType)\n const currentChain = useMemo(() => {\n return selectedChainId\n ? getChainById(selectedChainId, allChains)\n : undefined\n }, [selectedChainId, allChains, getChainById])\n const chains = useMemo(() => {\n return isAllNetworks ? allChains : currentChain ? [currentChain] : undefined\n }, [allChains, isAllNetworks, currentChain])\n\n const { accounts: allAccounts, account: currentAccount } = useAccount(\n isAllNetworks ? undefined : { chainType: currentChain?.chainType }\n )\n const accounts = useMemo(() => {\n return isAllNetworks\n ? allAccounts\n : currentAccount\n ? [currentAccount]\n : undefined\n }, [allAccounts, currentAccount, isAllNetworks])\n\n const accountsWithTokens = useMemo(() => {\n if (!chains || !allTokens || !accounts?.length) {\n return undefined\n }\n return accounts\n ?.filter((account) => account.address)\n .reduce(\n (acc, account) => {\n if (account.address) {\n const accountChains = chains?.filter(\n (chain) => account.chainType === chain?.chainType\n )\n if (accountChains) {\n const chainIdSet = new Set(accountChains.map((chain) => chain.id))\n const filteredTokens = Object.entries(allTokens).reduce(\n (tokenAcc, [chainIdStr, tokens]) => {\n const chainId = Number(chainIdStr)\n if (chainIdSet.has(chainId)) {\n tokenAcc[chainId] = tokens\n }\n return tokenAcc\n },\n {} as { [chainId: number]: TokenExtended[] }\n )\n acc[account.address] = {\n chainType: account.chainType,\n tokens: filteredTokens,\n }\n }\n }\n return acc\n },\n {} as Record<\n string,\n { chainType: ChainType; tokens: Record<number, TokenExtended[]> }\n >\n )\n }, [accounts, chains, allTokens])\n\n return {\n data: accountsWithTokens,\n isLoading: isChainsLoading,\n }\n}\n"],"mappings":";;;;;AAOA,MAAa,2BACX,iBACA,UACA,eACA,cAIG;CACH,MAAM,EAAE,MAAM,oBAAoB,WAAW,sBAC3C,gBAAgB,iBAAiB,UAAU,eAAe,SAAS;CAGrE,MAAM,EAAE,MAAM,gBAAgB,WAAW,4BACvC,2BAA2B,oBAAoB,QAAQ;CAEzD,OAAO;EACL,MAAM;EACN,WAAW,qBAAqB;CAClC;AACF;AAEA,MAAM,mBACJ,iBACA,UACA,eACA,cACG;CACH,MAAM,EACJ,QAAQ,WACR,WAAW,iBACX,iBACE,UAAU,QAAQ;CACtB,MAAM,eAAe,cAAc;EACjC,OAAO,kBACH,aAAa,iBAAiB,SAAS,IACvC,KAAA;CACN,GAAG;EAAC;EAAiB;EAAW;CAAY,CAAC;CAC7C,MAAM,SAAS,cAAc;EAC3B,OAAO,gBAAgB,YAAY,eAAe,CAAC,YAAY,IAAI,KAAA;CACrE,GAAG;EAAC;EAAW;EAAe;CAAY,CAAC;CAE3C,MAAM,EAAE,UAAU,aAAa,SAAS,mBAAmB,WACzD,gBAAgB,KAAA,IAAY,EAAE,WAAW,cAAc,UAAU,CACnE;CACA,MAAM,WAAW,cAAc;EAC7B,OAAO,gBACH,cACA,iBACE,CAAC,cAAc,IACf,KAAA;CACR,GAAG;EAAC;EAAa;EAAgB;CAAa,CAAC;CAyC/C,OAAO;EACL,MAxCyB,cAAc;GACvC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,QACtC;GAEF,OAAO,UACH,QAAQ,YAAY,QAAQ,OAAO,CAAC,CACrC,QACE,KAAK,YAAY;IAChB,IAAI,QAAQ,SAAS;KACnB,MAAM,gBAAgB,QAAQ,QAC3B,UAAU,QAAQ,cAAc,OAAO,SAC1C;KACA,IAAI,eAAe;MACjB,MAAM,aAAa,IAAI,IAAI,cAAc,KAAK,UAAU,MAAM,EAAE,CAAC;MACjE,MAAM,iBAAiB,OAAO,QAAQ,SAAS,CAAC,CAAC,QAC9C,UAAU,CAAC,YAAY,YAAY;OAClC,MAAM,UAAU,OAAO,UAAU;OACjC,IAAI,WAAW,IAAI,OAAO,GACxB,SAAS,WAAW;OAEtB,OAAO;MACT,GACA,CAAC,CACH;MACA,IAAI,QAAQ,WAAW;OACrB,WAAW,QAAQ;OACnB,QAAQ;MACV;KACF;IACF;IACA,OAAO;GACT,GACA,CAAC,CAIH;EACJ,GAAG;GAAC;GAAU;GAAQ;EAAS,CAGN;EACvB,WAAW;CACb;AACF"}
1
+ {"version":3,"file":"useAccountsBalancesData.js","names":[],"sources":["../../../src/hooks/useAccountsBalancesData.ts"],"sourcesContent":["import type { TokenExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport type { FormType } from '../stores/form/types.js'\nimport { useChains } from './useChains.js'\n\nexport const useAccountsBalancesData = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n allTokens?: Record<number, TokenExtended[]>\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const {\n chains: allChains,\n isLoading: isChainsLoading,\n getChainById,\n } = useChains(formType)\n const currentChain = useMemo(() => {\n return selectedChainId\n ? getChainById(selectedChainId, allChains)\n : undefined\n }, [selectedChainId, allChains, getChainById])\n const chains = useMemo(() => {\n return isAllNetworks ? allChains : currentChain ? [currentChain] : undefined\n }, [allChains, isAllNetworks, currentChain])\n\n const { accounts: allAccounts, account: currentAccount } = useAccount(\n isAllNetworks ? undefined : { chainType: currentChain?.chainType }\n )\n const accounts = useMemo(() => {\n return isAllNetworks\n ? allAccounts\n : currentAccount\n ? [currentAccount]\n : undefined\n }, [allAccounts, currentAccount, isAllNetworks])\n\n const accountsWithTokens = useMemo(() => {\n if (!chains || !allTokens || !accounts?.length) {\n return undefined\n }\n return accounts\n ?.filter((account) => account.address)\n .reduce(\n (acc, account) => {\n if (account.address) {\n const accountChains = chains?.filter(\n (chain) => account.chainType === chain?.chainType\n )\n if (accountChains) {\n const chainIdSet = new Set(accountChains.map((chain) => chain.id))\n acc[account.address] = Object.entries(allTokens).reduce(\n (tokenAcc, [chainIdStr, tokens]) => {\n const chainId = Number(chainIdStr)\n if (chainIdSet.has(chainId)) {\n tokenAcc[chainId] = tokens\n }\n return tokenAcc\n },\n {} as Record<number, TokenExtended[]>\n )\n }\n }\n return acc\n },\n {} as Record<string, Record<number, TokenExtended[]>>\n )\n }, [accounts, chains, allTokens])\n\n return {\n data: accountsWithTokens,\n isLoading: isChainsLoading,\n }\n}\n"],"mappings":";;;;AAMA,MAAa,2BACX,iBACA,UACA,eACA,cAIG;CACH,MAAM,EACJ,QAAQ,WACR,WAAW,iBACX,iBACE,UAAU,QAAQ;CACtB,MAAM,eAAe,cAAc;EACjC,OAAO,kBACH,aAAa,iBAAiB,SAAS,IACvC,KAAA;CACN,GAAG;EAAC;EAAiB;EAAW;CAAY,CAAC;CAC7C,MAAM,SAAS,cAAc;EAC3B,OAAO,gBAAgB,YAAY,eAAe,CAAC,YAAY,IAAI,KAAA;CACrE,GAAG;EAAC;EAAW;EAAe;CAAY,CAAC;CAE3C,MAAM,EAAE,UAAU,aAAa,SAAS,mBAAmB,WACzD,gBAAgB,KAAA,IAAY,EAAE,WAAW,cAAc,UAAU,CACnE;CACA,MAAM,WAAW,cAAc;EAC7B,OAAO,gBACH,cACA,iBACE,CAAC,cAAc,IACf,KAAA;CACR,GAAG;EAAC;EAAa;EAAgB;CAAa,CAAC;CAkC/C,OAAO;EACL,MAjCyB,cAAc;GACvC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,QACtC;GAEF,OAAO,UACH,QAAQ,YAAY,QAAQ,OAAO,CAAC,CACrC,QACE,KAAK,YAAY;IAChB,IAAI,QAAQ,SAAS;KACnB,MAAM,gBAAgB,QAAQ,QAC3B,UAAU,QAAQ,cAAc,OAAO,SAC1C;KACA,IAAI,eAAe;MACjB,MAAM,aAAa,IAAI,IAAI,cAAc,KAAK,UAAU,MAAM,EAAE,CAAC;MACjE,IAAI,QAAQ,WAAW,OAAO,QAAQ,SAAS,CAAC,CAAC,QAC9C,UAAU,CAAC,YAAY,YAAY;OAClC,MAAM,UAAU,OAAO,UAAU;OACjC,IAAI,WAAW,IAAI,OAAO,GACxB,SAAS,WAAW;OAEtB,OAAO;MACT,GACA,CAAC,CACH;KACF;IACF;IACA,OAAO;GACT,GACA,CAAC,CACH;EACJ,GAAG;GAAC;GAAU;GAAQ;EAAS,CAGN;EACvB,WAAW;CACb;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAvailableChains.d.ts","names":[],"sources":["../../../src/hooks/useAvailableChains.ts"],"mappings":";;;KAUK,gBACH,kBACA,SAAS,oBACN;cAUQ,qBACX,aAAa,aACb,eAAe;EAEf,QAAQ;EACR,cAAc;EACd"}
1
+ {"version":3,"file":"useAvailableChains.d.ts","names":[],"sources":["../../../src/hooks/useAvailableChains.ts"],"mappings":";;;KAUK,gBACH,kBACA,SAAS,oBACN;cAWQ,qBACX,aAAa,aACb,eAAe;EAEf,QAAQ;EACR,cAAc;EACd"}
@@ -11,7 +11,8 @@ const supportedChainTypes = [
11
11
  ChainType.SVM,
12
12
  ChainType.UTXO,
13
13
  ChainType.MVM,
14
- ChainType.TVM
14
+ ChainType.TVM,
15
+ ChainType.STL
15
16
  ];
16
17
  const useAvailableChains = (chainTypes, widgetConfig) => {
17
18
  const { chains: internalChains, keyPrefix: internalKeyPrefix } = useWidgetConfig();
@@ -1 +1 @@
1
- {"version":3,"file":"useAvailableChains.js","names":[],"sources":["../../../src/hooks/useAvailableChains.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { ChainType, createClient, getChains } from '@lifi/sdk'\nimport { useQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { WidgetConfig } from '../types/widget.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\n\ntype GetChainById = (\n chainId?: number,\n chains?: ExtendedChain[]\n) => ExtendedChain | undefined\n\nconst supportedChainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ChainType.TVM,\n]\n\nexport const useAvailableChains = (\n chainTypes?: ChainType[],\n widgetConfig?: WidgetConfig\n): {\n chains: ExtendedChain[] | undefined\n getChainById: GetChainById\n isLoading: boolean\n} => {\n const { chains: internalChains, keyPrefix: internalKeyPrefix } =\n useWidgetConfig()\n const internalClient = useSDKClient()\n\n const externalClient = useMemo(() => {\n if (!widgetConfig) {\n return undefined\n }\n return createClient({\n ...widgetConfig.sdkConfig,\n apiKey: widgetConfig.apiKey,\n integrator: widgetConfig.integrator ?? window?.location.hostname,\n })\n }, [widgetConfig])\n\n // Overwrite widget config if passed as param\n const keyPrefix = widgetConfig?.keyPrefix ?? internalKeyPrefix\n const chains = widgetConfig?.chains ?? internalChains\n\n const { data, isLoading } = useQuery({\n queryKey: [\n getQueryKey('chains', keyPrefix),\n chains?.types,\n chains?.allow,\n chains?.deny,\n chains?.from,\n chains?.to,\n !!externalClient,\n ] as const,\n queryFn: async ({ queryKey: [, chainTypesConfig] }) => {\n const chainsConfigSets = getConfigItemSets(\n chainTypesConfig,\n (chains) => new Set(chains)\n )\n const chainTypesRequest = supportedChainTypes.filter((chainType) =>\n isItemAllowedForSets(chainType, chainsConfigSets)\n )\n const client = externalClient ?? internalClient\n const availableChains = await getChains(client, {\n chainTypes: chainTypes || chainTypesRequest,\n })\n client.setChains(availableChains)\n return availableChains\n },\n refetchInterval: 300_000,\n staleTime: 300_000,\n })\n\n // Ensure the current internal client always has chains, even when:\n // - the query result came from cache (external call populated it first)\n // - the client was recreated due to config changes (stale closure in queryFn)\n useEffect(() => {\n if (data && !externalClient) {\n internalClient.setChains(data)\n }\n }, [data, externalClient, internalClient])\n\n const getChainById: GetChainById = useCallback(\n (chainId?: number, chains: ExtendedChain[] | undefined = data) => {\n if (!chainId) {\n return\n }\n const chain = chains?.find((chain) => chain.id === chainId)\n // if (!chain) {\n // throw new Error('Chain not found or chainId is invalid.');\n // }\n return chain\n },\n [data]\n )\n\n return {\n chains: data,\n getChainById,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;AAeA,MAAM,sBAAsB;CAC1B,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;AACZ;AAEA,MAAa,sBACX,YACA,iBAKG;CACH,MAAM,EAAE,QAAQ,gBAAgB,WAAW,sBACzC,gBAAgB;CAClB,MAAM,iBAAiB,aAAa;CAEpC,MAAM,iBAAiB,cAAc;EACnC,IAAI,CAAC,cACH;EAEF,OAAO,aAAa;GAClB,GAAG,aAAa;GAChB,QAAQ,aAAa;GACrB,YAAY,aAAa,cAAc,QAAQ,SAAS;EAC1D,CAAC;CACH,GAAG,CAAC,YAAY,CAAC;CAGjB,MAAM,YAAY,cAAc,aAAa;CAC7C,MAAM,SAAS,cAAc,UAAU;CAEvC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GACR,YAAY,UAAU,SAAS;GAC/B,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,CAAC,CAAC;EACJ;EACA,SAAS,OAAO,EAAE,UAAU,GAAG,wBAAwB;GACrD,MAAM,mBAAmB,kBACvB,mBACC,WAAW,IAAI,IAAI,MAAM,CAC5B;GACA,MAAM,oBAAoB,oBAAoB,QAAQ,cACpD,qBAAqB,WAAW,gBAAgB,CAClD;GACA,MAAM,SAAS,kBAAkB;GACjC,MAAM,kBAAkB,MAAM,UAAU,QAAQ,EAC9C,YAAY,cAAc,kBAC5B,CAAC;GACD,OAAO,UAAU,eAAe;GAChC,OAAO;EACT;EACA,iBAAiB;EACjB,WAAW;CACb,CAAC;CAKD,gBAAgB;EACd,IAAI,QAAQ,CAAC,gBACX,eAAe,UAAU,IAAI;CAEjC,GAAG;EAAC;EAAM;EAAgB;CAAc,CAAC;CAgBzC,OAAO;EACL,QAAQ;EACR,cAhBiC,aAChC,SAAkB,SAAsC,SAAS;GAChE,IAAI,CAAC,SACH;GAMF,OAJc,QAAQ,MAAM,UAAU,MAAM,OAAO,OAAO;EAK5D,GACA,CAAC,IAAI,CAKM;EACX;CACF;AACF"}
1
+ {"version":3,"file":"useAvailableChains.js","names":[],"sources":["../../../src/hooks/useAvailableChains.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { ChainType, createClient, getChains } from '@lifi/sdk'\nimport { useQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { WidgetConfig } from '../types/widget.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\n\ntype GetChainById = (\n chainId?: number,\n chains?: ExtendedChain[]\n) => ExtendedChain | undefined\n\nconst supportedChainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ChainType.TVM,\n ChainType.STL,\n]\n\nexport const useAvailableChains = (\n chainTypes?: ChainType[],\n widgetConfig?: WidgetConfig\n): {\n chains: ExtendedChain[] | undefined\n getChainById: GetChainById\n isLoading: boolean\n} => {\n const { chains: internalChains, keyPrefix: internalKeyPrefix } =\n useWidgetConfig()\n const internalClient = useSDKClient()\n\n const externalClient = useMemo(() => {\n if (!widgetConfig) {\n return undefined\n }\n return createClient({\n ...widgetConfig.sdkConfig,\n apiKey: widgetConfig.apiKey,\n integrator: widgetConfig.integrator ?? window?.location.hostname,\n })\n }, [widgetConfig])\n\n // Overwrite widget config if passed as param\n const keyPrefix = widgetConfig?.keyPrefix ?? internalKeyPrefix\n const chains = widgetConfig?.chains ?? internalChains\n\n const { data, isLoading } = useQuery({\n queryKey: [\n getQueryKey('chains', keyPrefix),\n chains?.types,\n chains?.allow,\n chains?.deny,\n chains?.from,\n chains?.to,\n !!externalClient,\n ] as const,\n queryFn: async ({ queryKey: [, chainTypesConfig] }) => {\n const chainsConfigSets = getConfigItemSets(\n chainTypesConfig,\n (chains) => new Set(chains)\n )\n const chainTypesRequest = supportedChainTypes.filter((chainType) =>\n isItemAllowedForSets(chainType, chainsConfigSets)\n )\n const client = externalClient ?? internalClient\n const availableChains = await getChains(client, {\n chainTypes: chainTypes || chainTypesRequest,\n })\n client.setChains(availableChains)\n return availableChains\n },\n refetchInterval: 300_000,\n staleTime: 300_000,\n })\n\n // Ensure the current internal client always has chains, even when:\n // - the query result came from cache (external call populated it first)\n // - the client was recreated due to config changes (stale closure in queryFn)\n useEffect(() => {\n if (data && !externalClient) {\n internalClient.setChains(data)\n }\n }, [data, externalClient, internalClient])\n\n const getChainById: GetChainById = useCallback(\n (chainId?: number, chains: ExtendedChain[] | undefined = data) => {\n if (!chainId) {\n return\n }\n const chain = chains?.find((chain) => chain.id === chainId)\n // if (!chain) {\n // throw new Error('Chain not found or chainId is invalid.');\n // }\n return chain\n },\n [data]\n )\n\n return {\n chains: data,\n getChainById,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;AAeA,MAAM,sBAAsB;CAC1B,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;AACZ;AAEA,MAAa,sBACX,YACA,iBAKG;CACH,MAAM,EAAE,QAAQ,gBAAgB,WAAW,sBACzC,gBAAgB;CAClB,MAAM,iBAAiB,aAAa;CAEpC,MAAM,iBAAiB,cAAc;EACnC,IAAI,CAAC,cACH;EAEF,OAAO,aAAa;GAClB,GAAG,aAAa;GAChB,QAAQ,aAAa;GACrB,YAAY,aAAa,cAAc,QAAQ,SAAS;EAC1D,CAAC;CACH,GAAG,CAAC,YAAY,CAAC;CAGjB,MAAM,YAAY,cAAc,aAAa;CAC7C,MAAM,SAAS,cAAc,UAAU;CAEvC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GACR,YAAY,UAAU,SAAS;GAC/B,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,CAAC,CAAC;EACJ;EACA,SAAS,OAAO,EAAE,UAAU,GAAG,wBAAwB;GACrD,MAAM,mBAAmB,kBACvB,mBACC,WAAW,IAAI,IAAI,MAAM,CAC5B;GACA,MAAM,oBAAoB,oBAAoB,QAAQ,cACpD,qBAAqB,WAAW,gBAAgB,CAClD;GACA,MAAM,SAAS,kBAAkB;GACjC,MAAM,kBAAkB,MAAM,UAAU,QAAQ,EAC9C,YAAY,cAAc,kBAC5B,CAAC;GACD,OAAO,UAAU,eAAe;GAChC,OAAO;EACT;EACA,iBAAiB;EACjB,WAAW;CACb,CAAC;CAKD,gBAAgB;EACd,IAAI,QAAQ,CAAC,gBACX,eAAe,UAAU,IAAI;CAEjC,GAAG;EAAC;EAAM;EAAgB;CAAc,CAAC;CAgBzC,OAAO;EACL,QAAQ;EACR,cAhBiC,aAChC,SAAkB,SAAsC,SAAS;GAChE,IAAI,CAAC,SACH;GAMF,OAJc,QAAQ,MAAM,UAAU,MAAM,OAAO,OAAO;EAK5D,GACA,CAAC,IAAI,CAKM;EACX;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"useExplorer.d.ts","names":[],"sources":["../../../src/hooks/useExplorer.ts"],"mappings":";;KAiBK;EACH,QAAQ;EACR;EACA;;cAGW;EACX,qBAAqB,OAAO;EAC5B,iBAAiB,iBAAiB,QAAQ"}
1
+ {"version":3,"file":"useExplorer.d.ts","names":[],"sources":["../../../src/hooks/useExplorer.ts"],"mappings":";;KAmBK;EACH,QAAQ;EACR;EACA;;cAGW;EACX,qBAAqB,OAAO;EAC5B,iBAAiB,iBAAiB,QAAQ"}
@@ -17,6 +17,10 @@ const explorerPathOverrides = {
17
17
  [ChainType.TVM]: {
18
18
  txPath: "#/transaction",
19
19
  addressPath: "#/address"
20
+ },
21
+ [ChainType.STL]: {
22
+ txPath: "tx",
23
+ addressPath: "account"
20
24
  }
21
25
  };
22
26
  const useExplorer = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"useExplorer.js","names":[],"sources":["../../../src/hooks/useExplorer.ts"],"sourcesContent":["import type { Chain } from '@lifi/sdk'\nimport { ChainId, ChainType, isHex } from '@lifi/sdk'\nimport { useCallback } from 'react'\nimport { internalExplorerUrl } from '../config/constants.js'\nimport { useAvailableChains } from '../hooks/useAvailableChains.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\n\nconst sanitiseBaseUrl = (baseUrl: string) => baseUrl.trim().replace(/\\/+$/, '')\n\nconst explorerPathOverrides: Partial<\n Record<ChainType | ChainId, { txPath: string; addressPath: string }>\n> = {\n [ChainId.SUI]: { txPath: 'txblock', addressPath: 'coin' },\n [ChainId.LTR]: { txPath: 'logs', addressPath: 'accounts' },\n [ChainType.TVM]: { txPath: '#/transaction', addressPath: '#/address' },\n}\n\ntype TransactionLinkProps = {\n chain?: Chain | number\n txHash?: string\n txLink?: string\n}\n\nexport const useExplorer = (): {\n getTransactionLink: (props: TransactionLinkProps) => string | undefined\n getAddressLink: (address: string, chain?: Chain | number) => string\n} => {\n const { explorerUrls } = useWidgetConfig()\n const { getChainById } = useAvailableChains()\n\n const getExplorerConfig = useCallback(\n (chain?: Chain | number) => {\n const resolvedChain = Number.isFinite(chain)\n ? getChainById(chain as number)\n : (chain as Chain)\n\n const explorerUrl =\n (resolvedChain\n ? (explorerUrls?.[resolvedChain.id]?.[0] ??\n resolvedChain.metamask.blockExplorerUrls[0])\n : explorerUrls?.internal?.[0]) || internalExplorerUrl\n\n const baseUrl =\n typeof explorerUrl === 'string' ? explorerUrl : explorerUrl.url\n\n const overrides =\n explorerPathOverrides[resolvedChain?.id as ChainId] ??\n explorerPathOverrides[resolvedChain?.chainType as ChainType]\n\n const defaultTxPath = overrides?.txPath ?? 'tx'\n const defaultAddressPath = overrides?.addressPath ?? 'address'\n const txPath =\n typeof explorerUrl === 'string'\n ? defaultTxPath\n : explorerUrl.txPath || defaultTxPath\n const addressPath =\n typeof explorerUrl === 'string'\n ? defaultAddressPath\n : explorerUrl.addressPath || defaultAddressPath\n\n return {\n url: sanitiseBaseUrl(baseUrl),\n txPath,\n addressPath,\n resolvedChain,\n hasOverride: Boolean(overrides),\n }\n },\n [explorerUrls, getChainById]\n )\n\n const getTransactionLink = useCallback(\n ({ txHash, txLink, chain }: TransactionLinkProps): string | undefined => {\n if (txHash) {\n const config = getExplorerConfig(chain)\n // For EVM chains, sanity-check the transaction hash as some relayers return custom task hashes that are not visible on-chain.\n // Skip the check when a chain-specific path override is registered — that's an explicit signal the chain's\n // explorer accepts a non-hex hash (e.g. Lighter, whose hash has no 0x prefix).\n const validForEvm =\n config.resolvedChain?.chainType !== ChainType.EVM ||\n config.hasOverride ||\n isHex(txHash, { strict: true })\n if (validForEvm) {\n return `${config.url}/${config.txPath}/${txHash}`\n }\n }\n return txLink\n },\n [getExplorerConfig]\n )\n\n const getAddressLink = useCallback(\n (address: string, chain?: Chain | number) => {\n const config = getExplorerConfig(chain)\n return `${config.url}/${config.addressPath}/${address}`\n },\n [getExplorerConfig]\n )\n\n return {\n getTransactionLink,\n getAddressLink,\n }\n}\n"],"mappings":";;;;;;AAOA,MAAM,mBAAmB,YAAoB,QAAQ,KAAK,CAAC,CAAC,QAAQ,QAAQ,EAAE;AAE9E,MAAM,wBAEF;EACD,QAAQ,MAAM;EAAE,QAAQ;EAAW,aAAa;CAAO;EACvD,QAAQ,MAAM;EAAE,QAAQ;EAAQ,aAAa;CAAW;EACxD,UAAU,MAAM;EAAE,QAAQ;EAAiB,aAAa;CAAY;AACvE;AAQA,MAAa,oBAGR;CACH,MAAM,EAAE,iBAAiB,gBAAgB;CACzC,MAAM,EAAE,iBAAiB,mBAAmB;CAE5C,MAAM,oBAAoB,aACvB,UAA2B;EAC1B,MAAM,gBAAgB,OAAO,SAAS,KAAK,IACvC,aAAa,KAAe,IAC3B;EAEL,MAAM,eACH,gBACI,eAAe,cAAc,GAAG,GAAG,MACpC,cAAc,SAAS,kBAAkB,KACzC,cAAc,WAAW,OAAA;EAE/B,MAAM,UACJ,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,MAAM,YACJ,sBAAsB,eAAe,OACrC,sBAAsB,eAAe;EAEvC,MAAM,gBAAgB,WAAW,UAAU;EAC3C,MAAM,qBAAqB,WAAW,eAAe;EACrD,MAAM,SACJ,OAAO,gBAAgB,WACnB,gBACA,YAAY,UAAU;EAC5B,MAAM,cACJ,OAAO,gBAAgB,WACnB,qBACA,YAAY,eAAe;EAEjC,OAAO;GACL,KAAK,gBAAgB,OAAO;GAC5B;GACA;GACA;GACA,aAAa,QAAQ,SAAS;EAChC;CACF,GACA,CAAC,cAAc,YAAY,CAC7B;CA8BA,OAAO;EACL,oBA7ByB,aACxB,EAAE,QAAQ,QAAQ,YAAsD;GACvE,IAAI,QAAQ;IACV,MAAM,SAAS,kBAAkB,KAAK;IAQtC,IAHE,OAAO,eAAe,cAAc,UAAU,OAC9C,OAAO,eACP,MAAM,QAAQ,EAAE,QAAQ,KAAK,CAAC,GAE9B,OAAO,GAAG,OAAO,IAAI,GAAG,OAAO,OAAO,GAAG;GAE7C;GACA,OAAO;EACT,GACA,CAAC,iBAAiB,CAYD;EACjB,gBAVqB,aACpB,SAAiB,UAA2B;GAC3C,MAAM,SAAS,kBAAkB,KAAK;GACtC,OAAO,GAAG,OAAO,IAAI,GAAG,OAAO,YAAY,GAAG;EAChD,GACA,CAAC,iBAAiB,CAKL;CACf;AACF"}
1
+ {"version":3,"file":"useExplorer.js","names":[],"sources":["../../../src/hooks/useExplorer.ts"],"sourcesContent":["import type { Chain } from '@lifi/sdk'\nimport { ChainId, ChainType, isHex } from '@lifi/sdk'\nimport { useCallback } from 'react'\nimport { internalExplorerUrl } from '../config/constants.js'\nimport { useAvailableChains } from '../hooks/useAvailableChains.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\n\nconst sanitiseBaseUrl = (baseUrl: string) => baseUrl.trim().replace(/\\/+$/, '')\n\nconst explorerPathOverrides: Partial<\n Record<ChainType | ChainId, { txPath: string; addressPath: string }>\n> = {\n [ChainId.SUI]: { txPath: 'txblock', addressPath: 'coin' },\n [ChainId.LTR]: { txPath: 'logs', addressPath: 'accounts' },\n [ChainType.TVM]: { txPath: '#/transaction', addressPath: '#/address' },\n // StellarExpert and steexp both route accounts at /account, never /address.\n [ChainType.STL]: { txPath: 'tx', addressPath: 'account' },\n}\n\ntype TransactionLinkProps = {\n chain?: Chain | number\n txHash?: string\n txLink?: string\n}\n\nexport const useExplorer = (): {\n getTransactionLink: (props: TransactionLinkProps) => string | undefined\n getAddressLink: (address: string, chain?: Chain | number) => string\n} => {\n const { explorerUrls } = useWidgetConfig()\n const { getChainById } = useAvailableChains()\n\n const getExplorerConfig = useCallback(\n (chain?: Chain | number) => {\n const resolvedChain = Number.isFinite(chain)\n ? getChainById(chain as number)\n : (chain as Chain)\n\n const explorerUrl =\n (resolvedChain\n ? (explorerUrls?.[resolvedChain.id]?.[0] ??\n resolvedChain.metamask.blockExplorerUrls[0])\n : explorerUrls?.internal?.[0]) || internalExplorerUrl\n\n const baseUrl =\n typeof explorerUrl === 'string' ? explorerUrl : explorerUrl.url\n\n const overrides =\n explorerPathOverrides[resolvedChain?.id as ChainId] ??\n explorerPathOverrides[resolvedChain?.chainType as ChainType]\n\n const defaultTxPath = overrides?.txPath ?? 'tx'\n const defaultAddressPath = overrides?.addressPath ?? 'address'\n const txPath =\n typeof explorerUrl === 'string'\n ? defaultTxPath\n : explorerUrl.txPath || defaultTxPath\n const addressPath =\n typeof explorerUrl === 'string'\n ? defaultAddressPath\n : explorerUrl.addressPath || defaultAddressPath\n\n return {\n url: sanitiseBaseUrl(baseUrl),\n txPath,\n addressPath,\n resolvedChain,\n hasOverride: Boolean(overrides),\n }\n },\n [explorerUrls, getChainById]\n )\n\n const getTransactionLink = useCallback(\n ({ txHash, txLink, chain }: TransactionLinkProps): string | undefined => {\n if (txHash) {\n const config = getExplorerConfig(chain)\n // For EVM chains, sanity-check the transaction hash as some relayers return custom task hashes that are not visible on-chain.\n // Skip the check when a chain-specific path override is registered — that's an explicit signal the chain's\n // explorer accepts a non-hex hash (e.g. Lighter, whose hash has no 0x prefix).\n const validForEvm =\n config.resolvedChain?.chainType !== ChainType.EVM ||\n config.hasOverride ||\n isHex(txHash, { strict: true })\n if (validForEvm) {\n return `${config.url}/${config.txPath}/${txHash}`\n }\n }\n return txLink\n },\n [getExplorerConfig]\n )\n\n const getAddressLink = useCallback(\n (address: string, chain?: Chain | number) => {\n const config = getExplorerConfig(chain)\n return `${config.url}/${config.addressPath}/${address}`\n },\n [getExplorerConfig]\n )\n\n return {\n getTransactionLink,\n getAddressLink,\n }\n}\n"],"mappings":";;;;;;AAOA,MAAM,mBAAmB,YAAoB,QAAQ,KAAK,CAAC,CAAC,QAAQ,QAAQ,EAAE;AAE9E,MAAM,wBAEF;EACD,QAAQ,MAAM;EAAE,QAAQ;EAAW,aAAa;CAAO;EACvD,QAAQ,MAAM;EAAE,QAAQ;EAAQ,aAAa;CAAW;EACxD,UAAU,MAAM;EAAE,QAAQ;EAAiB,aAAa;CAAY;EAEpE,UAAU,MAAM;EAAE,QAAQ;EAAM,aAAa;CAAU;AAC1D;AAQA,MAAa,oBAGR;CACH,MAAM,EAAE,iBAAiB,gBAAgB;CACzC,MAAM,EAAE,iBAAiB,mBAAmB;CAE5C,MAAM,oBAAoB,aACvB,UAA2B;EAC1B,MAAM,gBAAgB,OAAO,SAAS,KAAK,IACvC,aAAa,KAAe,IAC3B;EAEL,MAAM,eACH,gBACI,eAAe,cAAc,GAAG,GAAG,MACpC,cAAc,SAAS,kBAAkB,KACzC,cAAc,WAAW,OAAA;EAE/B,MAAM,UACJ,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAE9D,MAAM,YACJ,sBAAsB,eAAe,OACrC,sBAAsB,eAAe;EAEvC,MAAM,gBAAgB,WAAW,UAAU;EAC3C,MAAM,qBAAqB,WAAW,eAAe;EACrD,MAAM,SACJ,OAAO,gBAAgB,WACnB,gBACA,YAAY,UAAU;EAC5B,MAAM,cACJ,OAAO,gBAAgB,WACnB,qBACA,YAAY,eAAe;EAEjC,OAAO;GACL,KAAK,gBAAgB,OAAO;GAC5B;GACA;GACA;GACA,aAAa,QAAQ,SAAS;EAChC;CACF,GACA,CAAC,cAAc,YAAY,CAC7B;CA8BA,OAAO;EACL,oBA7ByB,aACxB,EAAE,QAAQ,QAAQ,YAAsD;GACvE,IAAI,QAAQ;IACV,MAAM,SAAS,kBAAkB,KAAK;IAQtC,IAHE,OAAO,eAAe,cAAc,UAAU,OAC9C,OAAO,eACP,MAAM,QAAQ,EAAE,QAAQ,KAAK,CAAC,GAE9B,OAAO,GAAG,OAAO,IAAI,GAAG,OAAO,OAAO,GAAG;GAE7C;GACA,OAAO;EACT,GACA,CAAC,iBAAiB,CAYD;EACjB,gBAVqB,aACpB,SAAiB,UAA2B;GAC3C,MAAM,SAAS,kBAAkB,KAAK;GACtC,OAAO,GAAG,OAAO,IAAI,GAAG,OAAO,YAAY,GAAG;EAChD,GACA,CAAC,iBAAiB,CAKL;CACf;AACF"}
@@ -0,0 +1,28 @@
1
+ import { useAvailableChains } from "./useAvailableChains.js";
2
+ import { getNativeTokenAddresses } from "../utils/token.js";
3
+ import { useMemo, useRef } from "react";
4
+ //#region src/hooks/useFlaggedTokenGuard.ts
5
+ /**
6
+ * Route tokens the screening provider flagged, and the sheet that warns about
7
+ * them before the transaction starts. A native token is exempt: the provider
8
+ * screens the native-address convention and calls it a scam on some chains.
9
+ */
10
+ const useFlaggedTokenGuard = (route) => {
11
+ const { chains } = useAvailableChains();
12
+ const flaggedTokenSheetRef = useRef(null);
13
+ return {
14
+ flaggedTokens: useMemo(() => {
15
+ const nativeTokenAddresses = getNativeTokenAddresses(chains);
16
+ return [route.fromToken, route.toToken].filter((token) => token.verificationStatus === "flagged" && nativeTokenAddresses.get(token.chainId)?.toLowerCase() !== token.address.toLowerCase());
17
+ }, [
18
+ chains,
19
+ route.fromToken,
20
+ route.toToken
21
+ ]),
22
+ flaggedTokenSheetRef
23
+ };
24
+ };
25
+ //#endregion
26
+ export { useFlaggedTokenGuard };
27
+
28
+ //# sourceMappingURL=useFlaggedTokenGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFlaggedTokenGuard.js","names":[],"sources":["../../../src/hooks/useFlaggedTokenGuard.ts"],"sourcesContent":["import type { RouteExtended, Token } from '@lifi/sdk'\nimport type { RefObject } from 'react'\nimport { useMemo, useRef } from 'react'\nimport type { BottomSheetBase } from '../components/BottomSheet/types.js'\nimport { getNativeTokenAddresses } from '../utils/token.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\n/**\n * Route tokens the screening provider flagged, and the sheet that warns about\n * them before the transaction starts. A native token is exempt: the provider\n * screens the native-address convention and calls it a scam on some chains.\n */\nexport const useFlaggedTokenGuard = (\n route: RouteExtended\n): {\n flaggedTokens: Token[]\n flaggedTokenSheetRef: RefObject<BottomSheetBase | null>\n} => {\n const { chains } = useAvailableChains()\n const flaggedTokenSheetRef = useRef<BottomSheetBase>(null)\n\n const flaggedTokens = useMemo(() => {\n const nativeTokenAddresses = getNativeTokenAddresses(chains)\n return [route.fromToken, route.toToken].filter(\n (token) =>\n token.verificationStatus === 'flagged' &&\n nativeTokenAddresses.get(token.chainId)?.toLowerCase() !==\n token.address.toLowerCase()\n )\n }, [chains, route.fromToken, route.toToken])\n\n return { flaggedTokens, flaggedTokenSheetRef }\n}\n"],"mappings":";;;;;;;;;AAYA,MAAa,wBACX,UAIG;CACH,MAAM,EAAE,WAAW,mBAAmB;CACtC,MAAM,uBAAuB,OAAwB,IAAI;CAYzD,OAAO;EAAE,eAVa,cAAc;GAClC,MAAM,uBAAuB,wBAAwB,MAAM;GAC3D,OAAO,CAAC,MAAM,WAAW,MAAM,OAAO,CAAC,CAAC,QACrC,UACC,MAAM,uBAAuB,aAC7B,qBAAqB,IAAI,MAAM,OAAO,CAAC,EAAE,YAAY,MACnD,MAAM,QAAQ,YAAY,CAChC;EACF,GAAG;GAAC;GAAQ,MAAM;GAAW,MAAM;EAAO,CAErB;EAAG;CAAqB;AAC/C"}
@@ -4,6 +4,7 @@ import { getQueryKey } from "../utils/queries.js";
4
4
  import { useAvailableChains } from "./useAvailableChains.js";
5
5
  import { useIsContractAddress } from "./useIsContractAddress.js";
6
6
  import { getTokenBalancesWithRetry } from "./useTokenBalance.js";
7
+ import { getSelfFundedGasAmount } from "../utils/gas.js";
7
8
  import { ChainType } from "@lifi/sdk";
8
9
  import { useMemo } from "react";
9
10
  import { useQuery } from "@tanstack/react-query";
@@ -49,7 +50,8 @@ const useGasSufficiency = (route) => {
49
50
  if (step.estimate.gasCosts && !skipDueToRefuel) {
50
51
  const { token } = step.estimate.gasCosts[0];
51
52
  const gasCostAmount = step.estimate.gasCosts.reduce((amount, gasCost) => amount + BigInt(Number(gasCost.amount).toFixed(0)), 0n);
52
- if (gasCostAmount > 0n) groupedGasCosts[token.chainId] = {
53
+ const selfFundedGasAmount = getSelfFundedGasAmount(route, step, getChainById(token.chainId)?.chainType);
54
+ if (gasCostAmount > 0n && gasCostAmount > selfFundedGasAmount) groupedGasCosts[token.chainId] = {
53
55
  gasAmount: groupedGasCosts[token.chainId] ? groupedGasCosts[token.chainId].gasAmount + gasCostAmount : gasCostAmount,
54
56
  token,
55
57
  chain: getChainById(token.chainId)
@@ -1 +1 @@
1
- {"version":3,"file":"useGasSufficiency.js","names":[],"sources":["../../../src/hooks/useGasSufficiency.ts"],"sourcesContent":["import type { EVMChain, RouteExtended, Token, TokenAmount } from '@lifi/sdk'\nimport { ChainType } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { getTokenBalancesWithRetry } from './useTokenBalance.js'\n\nexport interface GasSufficiency {\n gasAmount: bigint\n tokenAmount?: bigint\n insufficientAmount?: bigint\n insufficient?: boolean\n token: Token\n chain?: EVMChain\n}\n\nconst refetchInterval = 30_000\n\nexport const useGasSufficiency = (\n route?: RouteExtended\n): {\n insufficientGas: GasSufficiency[] | undefined\n isLoading: boolean\n} => {\n const { getChainById } = useAvailableChains()\n const { account: EVMAccount, accounts } = useAccount({\n chainType: ChainType.EVM,\n })\n const { keyPrefix, hiddenUI } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const { relevantAccounts, relevantAccountsQueryKey } = useMemo(() => {\n const chainTypes = route?.steps.reduce((acc, step) => {\n const chainType = getChainById(step.action.fromChainId)?.chainType\n if (chainType) {\n acc.add(chainType)\n }\n return acc\n }, new Set<ChainType>())\n\n const relevantAccounts = accounts.filter(\n (account) =>\n account.isConnected &&\n account.address &&\n chainTypes?.has(account.chainType)\n )\n return {\n relevantAccounts,\n relevantAccountsQueryKey: relevantAccounts\n .map((account) => account.address)\n .join(','),\n }\n }, [accounts, route?.steps, getChainById])\n\n const { isContractAddress, isLoading: isContractAddressLoading } =\n useIsContractAddress(\n EVMAccount.address,\n route?.fromChainId,\n EVMAccount.chainType\n )\n\n const { data: insufficientGas, isLoading } = useQuery<GasSufficiency[]>({\n queryKey: [\n getQueryKey('gas-sufficiency-check', keyPrefix),\n relevantAccountsQueryKey,\n route?.id,\n isContractAddress,\n ] as const,\n queryFn: async () => {\n if (!route) {\n return []\n }\n\n // Filter out steps that are relayer steps or have primaryType 'Permit' or 'Order'\n const filteredSteps = route.steps.filter(\n (step) =>\n !step.typedData?.some(\n (t) => t.primaryType === 'Permit' || t.primaryType === 'Order'\n )\n )\n\n // If all steps are filtered out, we don't need to check for gas sufficiency\n if (!filteredSteps.length) {\n return []\n }\n\n // We assume that LI.Fuel protocol always refuels the destination chain\n const hasRefuelStep = route.steps\n .flatMap((step) => step.includedSteps)\n .some((includedStep) => includedStep.tool === 'gasZip')\n\n const gasCosts = filteredSteps\n .filter((step) => step.execution?.status !== 'DONE')\n .reduce(\n (groupedGasCosts, step) => {\n // We need to avoid destination chain step sufficiency check if we have LI.Fuel protocol sub-step\n const skipDueToRefuel =\n step.action.fromChainId === route.toChainId && hasRefuelStep\n if (step.estimate.gasCosts && !skipDueToRefuel) {\n const { token } = step.estimate.gasCosts[0]\n const gasCostAmount = step.estimate.gasCosts.reduce(\n (amount, gasCost) =>\n amount + BigInt(Number(gasCost.amount).toFixed(0)),\n 0n\n )\n if (gasCostAmount > 0n) {\n groupedGasCosts[token.chainId] = {\n gasAmount: groupedGasCosts[token.chainId]\n ? groupedGasCosts[token.chainId].gasAmount + gasCostAmount\n : gasCostAmount,\n token,\n chain: getChainById(token.chainId),\n }\n }\n }\n // Add fees paid in native tokens to gas sufficiency check (included: false)\n const nonIncludedFeeCosts = step.estimate.feeCosts?.filter(\n (feeCost) => !feeCost.included\n )\n if (nonIncludedFeeCosts?.length) {\n const { token } = nonIncludedFeeCosts[0]\n const feeCostAmount = nonIncludedFeeCosts.reduce(\n (amount, feeCost) =>\n amount + BigInt(Number(feeCost.amount).toFixed(0)),\n 0n\n )\n if (feeCostAmount > 0n) {\n groupedGasCosts[token.chainId] = {\n gasAmount: groupedGasCosts[token.chainId]\n ? groupedGasCosts[token.chainId].gasAmount + feeCostAmount\n : feeCostAmount,\n token,\n chain: getChainById(token.chainId),\n }\n }\n }\n return groupedGasCosts\n },\n {} as Record<string, GasSufficiency>\n )\n\n // Check whether we are sending a native token\n // For native tokens we want to check for the total amount, including the network fee\n if (\n route.fromToken.address === gasCosts[route.fromChainId]?.token.address\n ) {\n gasCosts[route.fromChainId].tokenAmount =\n gasCosts[route.fromChainId]?.gasAmount + BigInt(route.fromAmount)\n }\n\n const gasCostsValues = Object.values(gasCosts)\n\n const balanceChecks = await Promise.allSettled(\n relevantAccounts.map((account) => {\n const relevantTokens = gasCostsValues\n .filter((gasCost) => gasCost.chain?.chainType === account.chainType)\n .map((item) => item.token)\n\n return getTokenBalancesWithRetry(\n sdkClient,\n account.address!,\n relevantTokens\n )\n })\n )\n\n const tokenBalances = balanceChecks\n .filter(\n (result): result is PromiseFulfilledResult<TokenAmount[]> =>\n result.status === 'fulfilled' && Boolean(result.value)\n )\n .flatMap((result) => result.value)\n\n if (!tokenBalances?.length) {\n return []\n }\n\n Object.keys(gasCosts).forEach((chainId) => {\n if (gasCosts[chainId]) {\n const gasTokenBalance =\n tokenBalances?.find(\n (t) =>\n t.chainId === gasCosts[chainId].token.chainId &&\n t.address === gasCosts[chainId].token.address\n )?.amount ?? 0n\n const insufficient =\n gasTokenBalance <= 0n ||\n gasTokenBalance < gasCosts[chainId].gasAmount ||\n gasTokenBalance < (gasCosts[chainId].tokenAmount ?? 0n)\n\n const insufficientAmount = insufficient\n ? gasCosts[chainId].tokenAmount\n ? gasCosts[chainId].tokenAmount! - gasTokenBalance\n : gasCosts[chainId].gasAmount - gasTokenBalance\n : undefined\n\n gasCosts[chainId] = {\n ...gasCosts[chainId],\n insufficient,\n insufficientAmount,\n chain: insufficient ? getChainById(Number(chainId)) : undefined,\n }\n }\n })\n\n const gasCostResult = Object.values(gasCosts).filter(\n (gasCost) => gasCost.insufficient\n )\n\n return gasCostResult\n },\n\n enabled: Boolean(\n !isContractAddress &&\n !isContractAddressLoading &&\n relevantAccounts.length > 0 &&\n route &&\n !hiddenUI?.insufficientGasMessage\n ),\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n return {\n insufficientGas,\n isLoading,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useGasSufficiency.js","names":[],"sources":["../../../src/hooks/useGasSufficiency.ts"],"sourcesContent":["import type { EVMChain, RouteExtended, Token, TokenAmount } from '@lifi/sdk'\nimport { ChainType } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getSelfFundedGasAmount } from '../utils/gas.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { getTokenBalancesWithRetry } from './useTokenBalance.js'\n\nexport interface GasSufficiency {\n gasAmount: bigint\n tokenAmount?: bigint\n insufficientAmount?: bigint\n insufficient?: boolean\n token: Token\n chain?: EVMChain\n}\n\nconst refetchInterval = 30_000\n\nexport const useGasSufficiency = (\n route?: RouteExtended\n): {\n insufficientGas: GasSufficiency[] | undefined\n isLoading: boolean\n} => {\n const { getChainById } = useAvailableChains()\n const { account: EVMAccount, accounts } = useAccount({\n chainType: ChainType.EVM,\n })\n const { keyPrefix, hiddenUI } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const { relevantAccounts, relevantAccountsQueryKey } = useMemo(() => {\n const chainTypes = route?.steps.reduce((acc, step) => {\n const chainType = getChainById(step.action.fromChainId)?.chainType\n if (chainType) {\n acc.add(chainType)\n }\n return acc\n }, new Set<ChainType>())\n\n const relevantAccounts = accounts.filter(\n (account) =>\n account.isConnected &&\n account.address &&\n chainTypes?.has(account.chainType)\n )\n return {\n relevantAccounts,\n relevantAccountsQueryKey: relevantAccounts\n .map((account) => account.address)\n .join(','),\n }\n }, [accounts, route?.steps, getChainById])\n\n const { isContractAddress, isLoading: isContractAddressLoading } =\n useIsContractAddress(\n EVMAccount.address,\n route?.fromChainId,\n EVMAccount.chainType\n )\n\n const { data: insufficientGas, isLoading } = useQuery<GasSufficiency[]>({\n queryKey: [\n getQueryKey('gas-sufficiency-check', keyPrefix),\n relevantAccountsQueryKey,\n route?.id,\n isContractAddress,\n ] as const,\n queryFn: async () => {\n if (!route) {\n return []\n }\n\n // Filter out steps that are relayer steps or have primaryType 'Permit' or 'Order'\n const filteredSteps = route.steps.filter(\n (step) =>\n !step.typedData?.some(\n (t) => t.primaryType === 'Permit' || t.primaryType === 'Order'\n )\n )\n\n // If all steps are filtered out, we don't need to check for gas sufficiency\n if (!filteredSteps.length) {\n return []\n }\n\n // We assume that LI.Fuel protocol always refuels the destination chain\n const hasRefuelStep = route.steps\n .flatMap((step) => step.includedSteps)\n .some((includedStep) => includedStep.tool === 'gasZip')\n\n const gasCosts = filteredSteps\n .filter((step) => step.execution?.status !== 'DONE')\n .reduce(\n (groupedGasCosts, step) => {\n // We need to avoid destination chain step sufficiency check if we have LI.Fuel protocol sub-step\n const skipDueToRefuel =\n step.action.fromChainId === route.toChainId && hasRefuelStep\n if (step.estimate.gasCosts && !skipDueToRefuel) {\n const { token } = step.estimate.gasCosts[0]\n const gasCostAmount = step.estimate.gasCosts.reduce(\n (amount, gasCost) =>\n amount + BigInt(Number(gasCost.amount).toFixed(0)),\n 0n\n )\n // A previous step can deliver this step's gas token (XLM bridged to\n // Stellar), so the user does not have to hold it up front\n const selfFundedGasAmount = getSelfFundedGasAmount(\n route,\n step,\n getChainById(token.chainId)?.chainType\n )\n if (gasCostAmount > 0n && gasCostAmount > selfFundedGasAmount) {\n groupedGasCosts[token.chainId] = {\n gasAmount: groupedGasCosts[token.chainId]\n ? groupedGasCosts[token.chainId].gasAmount + gasCostAmount\n : gasCostAmount,\n token,\n chain: getChainById(token.chainId),\n }\n }\n }\n // Add fees paid in native tokens to gas sufficiency check (included: false)\n const nonIncludedFeeCosts = step.estimate.feeCosts?.filter(\n (feeCost) => !feeCost.included\n )\n if (nonIncludedFeeCosts?.length) {\n const { token } = nonIncludedFeeCosts[0]\n const feeCostAmount = nonIncludedFeeCosts.reduce(\n (amount, feeCost) =>\n amount + BigInt(Number(feeCost.amount).toFixed(0)),\n 0n\n )\n if (feeCostAmount > 0n) {\n groupedGasCosts[token.chainId] = {\n gasAmount: groupedGasCosts[token.chainId]\n ? groupedGasCosts[token.chainId].gasAmount + feeCostAmount\n : feeCostAmount,\n token,\n chain: getChainById(token.chainId),\n }\n }\n }\n return groupedGasCosts\n },\n {} as Record<string, GasSufficiency>\n )\n\n // Check whether we are sending a native token\n // For native tokens we want to check for the total amount, including the network fee\n if (\n route.fromToken.address === gasCosts[route.fromChainId]?.token.address\n ) {\n gasCosts[route.fromChainId].tokenAmount =\n gasCosts[route.fromChainId]?.gasAmount + BigInt(route.fromAmount)\n }\n\n const gasCostsValues = Object.values(gasCosts)\n\n const balanceChecks = await Promise.allSettled(\n relevantAccounts.map((account) => {\n const relevantTokens = gasCostsValues\n .filter((gasCost) => gasCost.chain?.chainType === account.chainType)\n .map((item) => item.token)\n\n return getTokenBalancesWithRetry(\n sdkClient,\n account.address!,\n relevantTokens\n )\n })\n )\n\n const tokenBalances = balanceChecks\n .filter(\n (result): result is PromiseFulfilledResult<TokenAmount[]> =>\n result.status === 'fulfilled' && Boolean(result.value)\n )\n .flatMap((result) => result.value)\n\n if (!tokenBalances?.length) {\n return []\n }\n\n Object.keys(gasCosts).forEach((chainId) => {\n if (gasCosts[chainId]) {\n const gasTokenBalance =\n tokenBalances?.find(\n (t) =>\n t.chainId === gasCosts[chainId].token.chainId &&\n t.address === gasCosts[chainId].token.address\n )?.amount ?? 0n\n const insufficient =\n gasTokenBalance <= 0n ||\n gasTokenBalance < gasCosts[chainId].gasAmount ||\n gasTokenBalance < (gasCosts[chainId].tokenAmount ?? 0n)\n\n const insufficientAmount = insufficient\n ? gasCosts[chainId].tokenAmount\n ? gasCosts[chainId].tokenAmount! - gasTokenBalance\n : gasCosts[chainId].gasAmount - gasTokenBalance\n : undefined\n\n gasCosts[chainId] = {\n ...gasCosts[chainId],\n insufficient,\n insufficientAmount,\n chain: insufficient ? getChainById(Number(chainId)) : undefined,\n }\n }\n })\n\n const gasCostResult = Object.values(gasCosts).filter(\n (gasCost) => gasCost.insufficient\n )\n\n return gasCostResult\n },\n\n enabled: Boolean(\n !isContractAddress &&\n !isContractAddressLoading &&\n relevantAccounts.length > 0 &&\n route &&\n !hiddenUI?.insufficientGasMessage\n ),\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n return {\n insufficientGas,\n isLoading,\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { useGasRecommendation } from "./useGasRecommendation.js";
2
+ import { useTokenAddressBalance } from "./useTokenAddressBalance.js";
3
+ //#region src/hooks/useMaxSendAmount.ts
4
+ const useMaxSendAmount = (chainId, tokenAddress) => {
5
+ const { token, chain } = useTokenAddressBalance(chainId, tokenAddress);
6
+ const { data } = useGasRecommendation(chainId);
7
+ if (!token?.amount) return 0n;
8
+ if (chain?.nativeToken.address !== tokenAddress) return token.amount;
9
+ const reserved = BigInt(data?.recommended?.amount ?? 0);
10
+ return token.amount > reserved ? token.amount - reserved : token.amount;
11
+ };
12
+ //#endregion
13
+ export { useMaxSendAmount };
14
+
15
+ //# sourceMappingURL=useMaxSendAmount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMaxSendAmount.js","names":[],"sources":["../../../src/hooks/useMaxSendAmount.ts"],"sourcesContent":["import { useGasRecommendation } from './useGasRecommendation.js'\nimport { useTokenAddressBalance } from './useTokenAddressBalance.js'\n\n// Largest amount of the token the wallet can send: for the native token that is\n// the balance less the gas the chain recommends keeping back.\nexport const useMaxSendAmount = (\n chainId?: number,\n tokenAddress?: string\n): bigint => {\n const { token, chain } = useTokenAddressBalance(chainId, tokenAddress)\n const { data } = useGasRecommendation(chainId)\n\n if (!token?.amount) {\n return 0n\n }\n if (chain?.nativeToken.address !== tokenAddress) {\n return token.amount\n }\n const reserved = BigInt(data?.recommended?.amount ?? 0)\n return token.amount > reserved ? token.amount - reserved : token.amount\n}\n"],"mappings":";;;AAKA,MAAa,oBACX,SACA,iBACW;CACX,MAAM,EAAE,OAAO,UAAU,uBAAuB,SAAS,YAAY;CACrE,MAAM,EAAE,SAAS,qBAAqB,OAAO;CAE7C,IAAI,CAAC,OAAO,QACV,OAAO;CAET,IAAI,OAAO,YAAY,YAAY,cACjC,OAAO,MAAM;CAEf,MAAM,WAAW,OAAO,MAAM,aAAa,UAAU,CAAC;CACtD,OAAO,MAAM,SAAS,WAAW,MAAM,SAAS,WAAW,MAAM;AACnE"}
@@ -13,10 +13,11 @@ function usePacedRouteExecution({ routeId, onAcceptExchangeRateUpdate }) {
13
13
  routeId,
14
14
  onAcceptExchangeRateUpdate
15
15
  });
16
- const display = usePacedValue(useMemo(() => ({
16
+ const live = useMemo(() => ({
17
17
  route,
18
18
  status
19
- }), [route, status]), status !== 1);
19
+ }), [route, status]);
20
+ const display = usePacedValue(live, status !== 1);
20
21
  return {
21
22
  executeRoute,
22
23
  restartRoute,
@@ -1 +1 @@
1
- {"version":3,"file":"usePacedRouteExecution.js","names":[],"sources":["../../../src/hooks/usePacedRouteExecution.ts"],"sourcesContent":["import type { ExchangeRateUpdateParams, RouteExtended } from '@lifi/sdk'\nimport { useMemo } from 'react'\nimport { RouteExecutionStatus } from '../stores/routes/types.js'\nimport { usePacedValue } from './usePacedValue.js'\nimport { useRouteExecution } from './useRouteExecution.js'\n\ninterface PacedRouteExecutionProps {\n routeId: string\n onAcceptExchangeRateUpdate?(\n resolver: (value: boolean) => void,\n data: ExchangeRateUpdateParams\n ): void\n}\n\n/**\n * Wraps {@link useRouteExecution} and paces `route`/`status` so the\n * `ExecutionStatusCard` animation has time to play between updates. Only the\n * display is paced — events and store writes happen at the SDK's real speed.\n */\nexport function usePacedRouteExecution({\n routeId,\n onAcceptExchangeRateUpdate,\n}: PacedRouteExecutionProps): {\n executeRoute: () => void\n restartRoute: () => void\n deleteRoute: () => void\n route: RouteExtended | undefined\n status: RouteExecutionStatus | undefined\n} {\n const { executeRoute, restartRoute, deleteRoute, route, status } =\n useRouteExecution({ routeId, onAcceptExchangeRateUpdate })\n\n // Pace route and status as one value so they always match. Skip pacing while\n // Idle, so the review screen shows live data.\n const live = useMemo(() => ({ route, status }), [route, status])\n const display = usePacedValue(live, status !== RouteExecutionStatus.Idle)\n\n return {\n executeRoute,\n restartRoute,\n deleteRoute,\n route: display.route,\n status: display.status,\n }\n}\n"],"mappings":";;;;;;;;;;AAmBA,SAAgB,uBAAuB,EACrC,SACA,8BAOA;CACA,MAAM,EAAE,cAAc,cAAc,aAAa,OAAO,WACtD,kBAAkB;EAAE;EAAS;CAA2B,CAAC;CAK3D,MAAM,UAAU,cADH,eAAe;EAAE;EAAO;CAAO,IAAI,CAAC,OAAO,MAAM,CAC7B,GAAG,WAAA,CAAoC;CAExE,OAAO;EACL;EACA;EACA;EACA,OAAO,QAAQ;EACf,QAAQ,QAAQ;CAClB;AACF"}
1
+ {"version":3,"file":"usePacedRouteExecution.js","names":[],"sources":["../../../src/hooks/usePacedRouteExecution.ts"],"sourcesContent":["import type { ExchangeRateUpdateParams, RouteExtended } from '@lifi/sdk'\nimport { useMemo } from 'react'\nimport { RouteExecutionStatus } from '../stores/routes/types.js'\nimport { usePacedValue } from './usePacedValue.js'\nimport { useRouteExecution } from './useRouteExecution.js'\n\ninterface PacedRouteExecutionProps {\n routeId: string\n onAcceptExchangeRateUpdate?(\n resolver: (value: boolean) => void,\n data: ExchangeRateUpdateParams\n ): void\n}\n\n/**\n * Wraps {@link useRouteExecution} and paces `route`/`status` so the\n * `ExecutionStatusCard` animation has time to play between updates. Only the\n * display is paced — events and store writes happen at the SDK's real speed.\n */\nexport function usePacedRouteExecution({\n routeId,\n onAcceptExchangeRateUpdate,\n}: PacedRouteExecutionProps): {\n executeRoute: () => void\n restartRoute: () => void\n deleteRoute: () => void\n route: RouteExtended | undefined\n status: RouteExecutionStatus | undefined\n} {\n const { executeRoute, restartRoute, deleteRoute, route, status } =\n useRouteExecution({ routeId, onAcceptExchangeRateUpdate })\n\n // Pace route and status as one value so they always match. Skip pacing while\n // Idle, so the review screen shows live data.\n const live = useMemo(() => ({ route, status }), [route, status])\n const display = usePacedValue(live, status !== RouteExecutionStatus.Idle)\n\n return {\n executeRoute,\n restartRoute,\n deleteRoute,\n route: display.route,\n status: display.status,\n }\n}\n"],"mappings":";;;;;;;;;;AAmBA,SAAgB,uBAAuB,EACrC,SACA,8BAOA;CACA,MAAM,EAAE,cAAc,cAAc,aAAa,OAAO,WACtD,kBAAkB;EAAE;EAAS;CAA2B,CAAC;CAI3D,MAAM,OAAO,eAAe;EAAE;EAAO;CAAO,IAAI,CAAC,OAAO,MAAM,CAAC;CAC/D,MAAM,UAAU,cAAc,MAAM,WAAA,CAAoC;CAExE,OAAO;EACL;EACA;EACA;EACA,OAAO,QAAQ;EACf,QAAQ,QAAQ;CAClB;AACF"}
@@ -41,11 +41,12 @@ const useRouteExecutionMessage = (route, status) => {
41
41
  case 8: {
42
42
  const step = route.steps.find((step) => step.execution?.status === "FAILED");
43
43
  if (!step) break;
44
- const actionMessage = getErrorMessage(t, getChainById, step, step.execution?.actions?.find((action) => action.status === "FAILED") || {
44
+ const action = step.execution?.actions?.find((action) => action.status === "FAILED") || {
45
45
  status: "FAILED",
46
46
  type: "EXECUTION",
47
47
  error: step.execution?.error
48
- });
48
+ };
49
+ const actionMessage = getErrorMessage(t, getChainById, step, action);
49
50
  title = actionMessage.title;
50
51
  message = actionMessage.message;
51
52
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteExecutionMessage.js","names":[],"sources":["../../../src/hooks/useRouteExecutionMessage.ts"],"sourcesContent":["import type { ExecutionActionType, RouteExtended } from '@lifi/sdk'\nimport { useTranslation } from 'react-i18next'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { RouteExecutionStatus } from '../stores/routes/types.js'\nimport { getActionMessage } from '../utils/getActionMessage.js'\nimport { getErrorMessage } from '../utils/getErrorMessage.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\nexport const useRouteExecutionMessage = (\n route: RouteExtended,\n status: RouteExecutionStatus\n): { title: string | undefined; message: string | undefined } => {\n const { mode, modeOptions } = useWidgetConfig()\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n\n const transactionType =\n route.fromChainId === route.toChainId ? 'swap' : 'bridge'\n\n let title: string | undefined\n let message: string | undefined\n\n switch (status) {\n case RouteExecutionStatus.Pending: {\n // Use the first executing step, not the last one — in a multi-step route\n // the active step is often not the last.\n const activeStep =\n route.steps.find(\n (s) =>\n s.execution?.status === 'PENDING' ||\n s.execution?.status === 'ACTION_REQUIRED'\n ) ?? route.steps.at(-1)\n const lastAction = activeStep?.execution?.actions?.at(-1)\n const actionMessage =\n activeStep && lastAction\n ? getActionMessage(\n t,\n activeStep,\n lastAction.type,\n lastAction.status,\n lastAction.substatus,\n mode,\n modeOptions\n )\n : undefined\n // Fall back to a generic title when the step has no action to describe yet\n // (just after a restart, or before the first action exists).\n title =\n actionMessage?.title ?? t(`main.process.${transactionType}.pending`)\n message = actionMessage?.message\n break\n }\n case RouteExecutionStatus.Done: {\n title =\n mode === 'custom'\n ? t(\n `success.title.${modeOptions?.custom?.type ?? 'checkout'}Successful`\n )\n : t(`success.title.${transactionType}Successful`)\n break\n }\n case RouteExecutionStatus.Done | RouteExecutionStatus.Partial: {\n title = t(`success.title.${transactionType}PartiallySuccessful`)\n message = t('success.message.exchangePartiallySuccessful', {\n tool: route.steps.at(-1)?.toolDetails.name,\n tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,\n })\n break\n }\n case RouteExecutionStatus.Done | RouteExecutionStatus.Refunded: {\n title = t('success.title.refundIssued')\n message = t('success.message.exchangePartiallySuccessful', {\n tool: route.steps.at(-1)?.toolDetails.name,\n tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,\n })\n break\n }\n case RouteExecutionStatus.Failed: {\n const step = route.steps.find(\n (step) => step.execution?.status === 'FAILED'\n )\n if (!step) {\n break\n }\n const action = step.execution?.actions?.find(\n (action) => action.status === 'FAILED'\n ) || {\n status: 'FAILED',\n type: 'EXECUTION' as ExecutionActionType,\n error: step.execution?.error,\n } // synthetic action to represent a failed execution with no actions\n const actionMessage = getErrorMessage(t, getChainById, step, action)\n title = actionMessage.title\n message = actionMessage.message\n break\n }\n }\n\n return { title, message }\n}\n"],"mappings":";;;;;;;AAQA,MAAa,4BACX,OACA,WAC+D;CAC/D,MAAM,EAAE,MAAM,gBAAgB,gBAAgB;CAC9C,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAE5C,MAAM,kBACJ,MAAM,gBAAgB,MAAM,YAAY,SAAS;CAEnD,IAAI;CACJ,IAAI;CAEJ,QAAQ,QAAR;EACE,KAAA,GAAmC;GAGjC,MAAM,aACJ,MAAM,MAAM,MACT,MACC,EAAE,WAAW,WAAW,aACxB,EAAE,WAAW,WAAW,iBAC5B,KAAK,MAAM,MAAM,GAAG,EAAE;GACxB,MAAM,aAAa,YAAY,WAAW,SAAS,GAAG,EAAE;GACxD,MAAM,gBACJ,cAAc,aACV,iBACE,GACA,YACA,WAAW,MACX,WAAW,QACX,WAAW,WACX,MACA,WACF,IACA,KAAA;GAGN,QACE,eAAe,SAAS,EAAE,gBAAgB,gBAAgB,SAAS;GACrE,UAAU,eAAe;GACzB;EACF;EACA,KAAA;GACE,QACE,SAAS,WACL,EACE,iBAAiB,aAAa,QAAQ,QAAQ,WAAW,WAC3D,IACA,EAAE,iBAAiB,gBAAgB,WAAW;GACpD;EAEF,KAAA;GACE,QAAQ,EAAE,iBAAiB,gBAAgB,oBAAoB;GAC/D,UAAU,EAAE,+CAA+C;IACzD,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY;IACtC,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,QAAQ;GAClD,CAAC;GACD;EAEF,KAAA;GACE,QAAQ,EAAE,4BAA4B;GACtC,UAAU,EAAE,+CAA+C;IACzD,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY;IACtC,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,QAAQ;GAClD,CAAC;GACD;EAEF,KAAA,GAAkC;GAChC,MAAM,OAAO,MAAM,MAAM,MACtB,SAAS,KAAK,WAAW,WAAW,QACvC;GACA,IAAI,CAAC,MACH;GASF,MAAM,gBAAgB,gBAAgB,GAAG,cAAc,MAPxC,KAAK,WAAW,SAAS,MACrC,WAAW,OAAO,WAAW,QAChC,KAAK;IACH,QAAQ;IACR,MAAM;IACN,OAAO,KAAK,WAAW;GACzB,CACmE;GACnE,QAAQ,cAAc;GACtB,UAAU,cAAc;GACxB;EACF;CACF;CAEA,OAAO;EAAE;EAAO;CAAQ;AAC1B"}
1
+ {"version":3,"file":"useRouteExecutionMessage.js","names":[],"sources":["../../../src/hooks/useRouteExecutionMessage.ts"],"sourcesContent":["import type { ExecutionActionType, RouteExtended } from '@lifi/sdk'\nimport { useTranslation } from 'react-i18next'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { RouteExecutionStatus } from '../stores/routes/types.js'\nimport { getActionMessage } from '../utils/getActionMessage.js'\nimport { getErrorMessage } from '../utils/getErrorMessage.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\nexport const useRouteExecutionMessage = (\n route: RouteExtended,\n status: RouteExecutionStatus\n): { title: string | undefined; message: string | undefined } => {\n const { mode, modeOptions } = useWidgetConfig()\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n\n const transactionType =\n route.fromChainId === route.toChainId ? 'swap' : 'bridge'\n\n let title: string | undefined\n let message: string | undefined\n\n switch (status) {\n case RouteExecutionStatus.Pending: {\n // Use the first executing step, not the last one — in a multi-step route\n // the active step is often not the last.\n const activeStep =\n route.steps.find(\n (s) =>\n s.execution?.status === 'PENDING' ||\n s.execution?.status === 'ACTION_REQUIRED'\n ) ?? route.steps.at(-1)\n const lastAction = activeStep?.execution?.actions?.at(-1)\n const actionMessage =\n activeStep && lastAction\n ? getActionMessage(\n t,\n activeStep,\n lastAction.type,\n lastAction.status,\n lastAction.substatus,\n mode,\n modeOptions\n )\n : undefined\n // Fall back to a generic title when the step has no action to describe yet\n // (just after a restart, or before the first action exists).\n title =\n actionMessage?.title ?? t(`main.process.${transactionType}.pending`)\n message = actionMessage?.message\n break\n }\n case RouteExecutionStatus.Done: {\n title =\n mode === 'custom'\n ? t(\n `success.title.${modeOptions?.custom?.type ?? 'checkout'}Successful`\n )\n : t(`success.title.${transactionType}Successful`)\n break\n }\n case RouteExecutionStatus.Done | RouteExecutionStatus.Partial: {\n title = t(`success.title.${transactionType}PartiallySuccessful`)\n message = t('success.message.exchangePartiallySuccessful', {\n tool: route.steps.at(-1)?.toolDetails.name,\n tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,\n })\n break\n }\n case RouteExecutionStatus.Done | RouteExecutionStatus.Refunded: {\n title = t('success.title.refundIssued')\n message = t('success.message.exchangePartiallySuccessful', {\n tool: route.steps.at(-1)?.toolDetails.name,\n tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,\n })\n break\n }\n case RouteExecutionStatus.Failed: {\n const step = route.steps.find(\n (step) => step.execution?.status === 'FAILED'\n )\n if (!step) {\n break\n }\n const action = step.execution?.actions?.find(\n (action) => action.status === 'FAILED'\n ) || {\n status: 'FAILED',\n type: 'EXECUTION' as ExecutionActionType,\n error: step.execution?.error,\n } // synthetic action to represent a failed execution with no actions\n const actionMessage = getErrorMessage(t, getChainById, step, action)\n title = actionMessage.title\n message = actionMessage.message\n break\n }\n }\n\n return { title, message }\n}\n"],"mappings":";;;;;;;AAQA,MAAa,4BACX,OACA,WAC+D;CAC/D,MAAM,EAAE,MAAM,gBAAgB,gBAAgB;CAC9C,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAE5C,MAAM,kBACJ,MAAM,gBAAgB,MAAM,YAAY,SAAS;CAEnD,IAAI;CACJ,IAAI;CAEJ,QAAQ,QAAR;EACE,KAAA,GAAmC;GAGjC,MAAM,aACJ,MAAM,MAAM,MACT,MACC,EAAE,WAAW,WAAW,aACxB,EAAE,WAAW,WAAW,iBAC5B,KAAK,MAAM,MAAM,GAAG,EAAE;GACxB,MAAM,aAAa,YAAY,WAAW,SAAS,GAAG,EAAE;GACxD,MAAM,gBACJ,cAAc,aACV,iBACE,GACA,YACA,WAAW,MACX,WAAW,QACX,WAAW,WACX,MACA,WACF,IACA,KAAA;GAGN,QACE,eAAe,SAAS,EAAE,gBAAgB,gBAAgB,SAAS;GACrE,UAAU,eAAe;GACzB;EACF;EACA,KAAA;GACE,QACE,SAAS,WACL,EACE,iBAAiB,aAAa,QAAQ,QAAQ,WAAW,WAC3D,IACA,EAAE,iBAAiB,gBAAgB,WAAW;GACpD;EAEF,KAAA;GACE,QAAQ,EAAE,iBAAiB,gBAAgB,oBAAoB;GAC/D,UAAU,EAAE,+CAA+C;IACzD,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY;IACtC,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,QAAQ;GAClD,CAAC;GACD;EAEF,KAAA;GACE,QAAQ,EAAE,4BAA4B;GACtC,UAAU,EAAE,+CAA+C;IACzD,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY;IACtC,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,QAAQ;GAClD,CAAC;GACD;EAEF,KAAA,GAAkC;GAChC,MAAM,OAAO,MAAM,MAAM,MACtB,SAAS,KAAK,WAAW,WAAW,QACvC;GACA,IAAI,CAAC,MACH;GAEF,MAAM,SAAS,KAAK,WAAW,SAAS,MACrC,WAAW,OAAO,WAAW,QAChC,KAAK;IACH,QAAQ;IACR,MAAM;IACN,OAAO,KAAK,WAAW;GACzB;GACA,MAAM,gBAAgB,gBAAgB,GAAG,cAAc,MAAM,MAAM;GACnE,QAAQ,cAAc;GACtB,UAAU,cAAc;GACxB;EACF;CACF;CAEA,OAAO;EAAE;EAAO;CAAQ;AAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRoutes.d.ts","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"mappings":";;UA2CU;EACR,kBAAkB;;;;;EAKlB;;;;;EAKA;;cAGW,cACX,iBACA,kBACA,kBAAkB,4BACjB;EACD,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA,qBAAqB,OAAO"}
1
+ {"version":3,"file":"useRoutes.d.ts","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"mappings":";;UA4CU;EACR,kBAAkB;;;;;EAKlB;;;;;EAKA;;cAGW,cACX,iBACA,kBACA,kBAAkB,4BACjB;EACD,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA,qBAAqB,OAAO"}
@@ -9,6 +9,7 @@ import { useFieldValues } from "../stores/form/useFieldValues.js";
9
9
  import { useIntermediateRoutesStore } from "../stores/routes/useIntermediateRoutesStore.js";
10
10
  import { useSetExecutableRoute } from "../stores/routes/useSetExecutableRoute.js";
11
11
  import { useSettings } from "../stores/settings/useSettings.js";
12
+ import { isCustomReceiverUnsupported } from "../utils/customReceiver.js";
12
13
  import { updateTokenInCache } from "../utils/token.js";
13
14
  import { useChain } from "./useChain.js";
14
15
  import { useDebouncedWatch } from "./useDebouncedWatch.js";
@@ -58,11 +59,12 @@ const useRoutes = ({ observableRoute, quoteFromAddress, keepPreviousData: keepPr
58
59
  const effectiveFromAddress = account.address ?? quoteFromAddress;
59
60
  const hasToAddressAndChainTypeSatisfied = !!toChain && !!toAddress && getChainTypeFromAddress(toAddress) === toChain.chainType;
60
61
  const isToAddressSatisfied = toAddress ? hasToAddressAndChainTypeSatisfied : true;
62
+ const customReceiverBlocked = isCustomReceiverUnsupported(fromChain?.chainType, toChain?.chainType) && Boolean(toAddress);
61
63
  const toWalletAddress = toAddress || void 0;
62
64
  const allowedBridges = bridges?.allow?.length || bridges?.deny?.length ? enabledBridges : void 0;
63
65
  const allowedExchanges = exchanges?.allow?.length || exchanges?.deny?.length ? enabledExchanges : void 0;
64
66
  const allowSwitchChain = sdkClient.config?.routeOptions?.allowSwitchChain;
65
- const isEnabled = Boolean(Number(fromChain?.id)) && Boolean(Number(toChain?.id)) && Boolean(fromToken?.address) && Boolean(toToken?.address) && !Number.isNaN(slippage) && hasAmount && isToAddressSatisfied && contractCallQuoteEnabled && !isBatchingSupportedLoading;
67
+ const isEnabled = Boolean(Number(fromChain?.id)) && Boolean(Number(toChain?.id)) && Boolean(fromToken?.address) && Boolean(toToken?.address) && !Number.isNaN(slippage) && hasAmount && isToAddressSatisfied && !customReceiverBlocked && contractCallQuoteEnabled && !isBatchingSupportedLoading;
66
68
  const queryKey = useMemo(() => [
67
69
  getQueryKey("routes", keyPrefix),
68
70
  effectiveFromAddress,