@lifi/widget 4.0.0-beta.14 → 4.0.0-beta.17

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 (206) hide show
  1. package/dist/esm/AppDefault.js +31 -29
  2. package/dist/esm/AppDefault.js.map +1 -1
  3. package/dist/esm/AppLayout.js +2 -2
  4. package/dist/esm/AppLayout.js.map +1 -1
  5. package/dist/esm/components/AmountInput/AmountInput.js +2 -2
  6. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  7. package/dist/esm/components/AppContainer.js +3 -3
  8. package/dist/esm/components/AppContainer.js.map +1 -1
  9. package/dist/esm/components/Chains/AllChainsAvatar.js +6 -0
  10. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
  11. package/dist/esm/components/ContractComponent/ItemPrice.js +1 -1
  12. package/dist/esm/components/ContractComponent/ItemPrice.js.map +1 -1
  13. package/dist/esm/components/ContractComponent/NFT/NFTBase.js +1 -1
  14. package/dist/esm/components/ContractComponent/NFT/NFTBase.js.map +1 -1
  15. package/dist/esm/components/Expansion/Expansion.js +4 -4
  16. package/dist/esm/components/Expansion/Expansion.js.map +1 -1
  17. package/dist/esm/components/Header/ActivitiesButton.js +1 -1
  18. package/dist/esm/components/Header/ActivitiesButton.js.map +1 -1
  19. package/dist/esm/components/Header/Header.js +2 -2
  20. package/dist/esm/components/Header/Header.js.map +1 -1
  21. package/dist/esm/components/Header/NavigationHeader.js +3 -3
  22. package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
  23. package/dist/esm/components/Header/WalletHeader.js +3 -3
  24. package/dist/esm/components/Header/WalletHeader.js.map +1 -1
  25. package/dist/esm/components/IconTypography.js.map +1 -1
  26. package/dist/esm/components/Messages/AlertMessage.js +1 -1
  27. package/dist/esm/components/Messages/AlertMessage.js.map +1 -1
  28. package/dist/esm/components/PageEntered.js +2 -2
  29. package/dist/esm/components/PageEntered.js.map +1 -1
  30. package/dist/esm/components/RouteCard/RouteCard.js +2 -2
  31. package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
  32. package/dist/esm/components/RouteCard/RouteCardEssentials.js +10 -4
  33. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  34. package/dist/esm/components/RouteCard/RouteToken.js +2 -2
  35. package/dist/esm/components/RouteCard/RouteToken.js.map +1 -1
  36. package/dist/esm/components/Routes/RoutesExpanded.js +3 -3
  37. package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
  38. package/dist/esm/components/SelectChainAndToken.js +8 -5
  39. package/dist/esm/components/SelectChainAndToken.js.map +1 -1
  40. package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js +1 -2
  41. package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js.map +1 -1
  42. package/dist/esm/components/SendToWallet/SendToWalletButton.js +3 -3
  43. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  44. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +3 -3
  45. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  46. package/dist/esm/components/Step/Step.js +20 -9
  47. package/dist/esm/components/Step/Step.js.map +1 -1
  48. package/dist/esm/components/Step/StepActions.js +2 -2
  49. package/dist/esm/components/Step/StepActions.js.map +1 -1
  50. package/dist/esm/components/StepActions/StepActions.js +2 -2
  51. package/dist/esm/components/StepActions/StepActions.js.map +1 -1
  52. package/dist/esm/components/Timer/TimerContent.js +1 -0
  53. package/dist/esm/components/Timer/TimerContent.js.map +1 -1
  54. package/dist/esm/components/Token/Token.js +2 -2
  55. package/dist/esm/components/Token/Token.js.map +1 -1
  56. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +6 -4
  57. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
  58. package/dist/esm/components/TokenList/TokenList.js +2 -2
  59. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  60. package/dist/esm/components/TokenList/useTokenSelect.js +2 -2
  61. package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
  62. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +2 -3
  63. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
  64. package/dist/esm/components/TransactionDetails.js +5 -2
  65. package/dist/esm/components/TransactionDetails.js.map +1 -1
  66. package/dist/esm/config/version.d.ts +1 -1
  67. package/dist/esm/config/version.js +1 -1
  68. package/dist/esm/config/version.js.map +1 -1
  69. package/dist/esm/hooks/useAddressValidation.js +3 -8
  70. package/dist/esm/hooks/useAddressValidation.js.map +1 -1
  71. package/dist/esm/hooks/useAvailableChains.js +2 -1
  72. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  73. package/dist/esm/hooks/useContactSupport.js +3 -3
  74. package/dist/esm/hooks/useContactSupport.js.map +1 -1
  75. package/dist/esm/hooks/useExplorer.js +15 -4
  76. package/dist/esm/hooks/useExplorer.js.map +1 -1
  77. package/dist/esm/hooks/useGasRecommendation.js +2 -2
  78. package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
  79. package/dist/esm/hooks/useGasRefuel.js +2 -2
  80. package/dist/esm/hooks/useGasRefuel.js.map +1 -1
  81. package/dist/esm/hooks/useGasSufficiency.js +2 -2
  82. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  83. package/dist/esm/hooks/useHasChainExpansion.js +3 -3
  84. package/dist/esm/hooks/useHasChainExpansion.js.map +1 -1
  85. package/dist/esm/hooks/useListHeight.js +2 -2
  86. package/dist/esm/hooks/useListHeight.js.map +1 -1
  87. package/dist/esm/hooks/useRouteExecution.js +5 -5
  88. package/dist/esm/hooks/useRouteExecution.js.map +1 -1
  89. package/dist/esm/hooks/useRoutes.js +4 -4
  90. package/dist/esm/hooks/useRoutes.js.map +1 -1
  91. package/dist/esm/hooks/useToAddressRequirements.js +2 -2
  92. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  93. package/dist/esm/hooks/useToAddressReset.js +2 -2
  94. package/dist/esm/hooks/useToAddressReset.js.map +1 -1
  95. package/dist/esm/hooks/useTokenBalances.js +2 -2
  96. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  97. package/dist/esm/hooks/useTokens.js +4 -2
  98. package/dist/esm/hooks/useTokens.js.map +1 -1
  99. package/dist/esm/hooks/useTransactionList.js +2 -3
  100. package/dist/esm/hooks/useTransactionList.js.map +1 -1
  101. package/dist/esm/i18n/en.json +3 -0
  102. package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js +1 -2
  103. package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js.map +1 -1
  104. package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js +1 -1
  105. package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js.map +1 -1
  106. package/dist/esm/pages/MainPage/MainPage.js +6 -6
  107. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  108. package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
  109. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  110. package/dist/esm/pages/RoutesPage/RoutesPage.js +3 -3
  111. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  112. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +3 -3
  113. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  114. package/dist/esm/pages/SendToWallet/BookmarksPage.js +1 -1
  115. package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  116. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +1 -1
  117. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  118. package/dist/esm/pages/SendToWallet/SendToWalletPage.js +6 -6
  119. package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  120. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
  121. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
  122. package/dist/esm/pages/SettingsPage/LanguageSetting.js +2 -2
  123. package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
  124. package/dist/esm/pages/SettingsPage/SettingsPage.js +2 -2
  125. package/dist/esm/pages/SettingsPage/SettingsPage.js.map +1 -1
  126. package/dist/esm/pages/SettingsPage/ThemeSettings.js +2 -2
  127. package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  128. package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js +2 -2
  129. package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -1
  130. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js +2 -2
  131. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js.map +1 -1
  132. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js +1 -1
  133. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
  134. package/dist/esm/pages/TransactionPage/StatusBottomSheet.js +20 -21
  135. package/dist/esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
  136. package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js +5 -6
  137. package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
  138. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +14 -4
  139. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  140. package/dist/esm/pages/TransactionPage/TransactionPage.js +15 -19
  141. package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  142. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
  143. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
  144. package/dist/esm/stores/chains/ChainOrderStore.js +2 -2
  145. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  146. package/dist/esm/stores/chains/createChainOrderStore.js +2 -2
  147. package/dist/esm/stores/chains/createChainOrderStore.js.map +1 -1
  148. package/dist/esm/stores/form/useFieldActions.js +3 -3
  149. package/dist/esm/stores/form/useFieldActions.js.map +1 -1
  150. package/dist/esm/stores/form/useFormRef.js +2 -2
  151. package/dist/esm/stores/form/useFormRef.js.map +1 -1
  152. package/dist/esm/stores/routes/createRouteExecutionStore.js +8 -9
  153. package/dist/esm/stores/routes/createRouteExecutionStore.js.map +1 -1
  154. package/dist/esm/stores/routes/useRouteExecutionIndicator.js +2 -3
  155. package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
  156. package/dist/esm/stores/settings/createSettingsStore.js +1 -5
  157. package/dist/esm/stores/settings/createSettingsStore.js.map +1 -1
  158. package/dist/esm/stores/settings/useSettingsActions.js +2 -2
  159. package/dist/esm/stores/settings/useSettingsActions.js.map +1 -1
  160. package/dist/esm/themes/createTheme.js +4 -4
  161. package/dist/esm/themes/createTheme.js.map +1 -1
  162. package/dist/esm/types/events.d.ts +0 -5
  163. package/dist/esm/types/events.d.ts.map +1 -1
  164. package/dist/esm/types/events.js +0 -4
  165. package/dist/esm/types/events.js.map +1 -1
  166. package/dist/esm/types/widget.d.ts +1 -5
  167. package/dist/esm/types/widget.d.ts.map +1 -1
  168. package/dist/esm/types/widget.js.map +1 -1
  169. package/dist/esm/utils/elements.js +5 -12
  170. package/dist/esm/utils/elements.js.map +1 -1
  171. package/package.json +7 -7
  172. package/src/AppDefault.tsx +9 -11
  173. package/src/components/Chains/AllChainsAvatar.tsx +6 -0
  174. package/src/components/ContractComponent/ItemPrice.tsx +1 -1
  175. package/src/components/ContractComponent/NFT/NFTBase.tsx +1 -1
  176. package/src/components/Header/ActivitiesButton.tsx +1 -1
  177. package/src/components/IconTypography.ts +8 -8
  178. package/src/components/Messages/AlertMessage.tsx +1 -1
  179. package/src/components/RouteCard/RouteCardEssentials.tsx +2 -2
  180. package/src/components/SelectChainAndToken.tsx +1 -1
  181. package/src/components/Step/Step.tsx +6 -7
  182. package/src/components/Timer/TimerContent.tsx +1 -0
  183. package/src/components/Token/Token.tsx +2 -2
  184. package/src/components/TokenList/TokenDetailsSheetContent.tsx +6 -4
  185. package/src/components/TransactionCard/ActiveTransactionCard.tsx +1 -1
  186. package/src/components/TransactionDetails.tsx +1 -1
  187. package/src/config/version.ts +1 -1
  188. package/src/hooks/useAvailableChains.ts +1 -0
  189. package/src/hooks/useExplorer.ts +16 -5
  190. package/src/hooks/useTokens.ts +2 -0
  191. package/src/pages/ActivitiesPage/ActivitiesPageMenuButton.tsx +1 -1
  192. package/src/pages/MainPage/MainPage.tsx +3 -3
  193. package/src/pages/RoutesPage/RoutesPage.tsx +6 -1
  194. package/src/pages/SendToWallet/BookmarksPage.tsx +1 -1
  195. package/src/pages/SendToWallet/RecentWalletsPage.tsx +1 -1
  196. package/src/pages/TransactionPage/ExchangeRateBottomSheet.tsx +1 -1
  197. package/src/pages/TransactionPage/StatusBottomSheet.tsx +1 -1
  198. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +27 -5
  199. package/src/pages/TransactionPage/TransactionPage.tsx +2 -9
  200. package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
  201. package/src/stores/settings/createSettingsStore.ts +1 -9
  202. package/src/themes/createTheme.ts +4 -6
  203. package/src/types/events.ts +0 -5
  204. package/src/types/widget.ts +1 -4
  205. package/dist/esm/stores/routes/types.js +0 -14
  206. package/dist/esm/stores/routes/types.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TransactionDetails.js","names":["Card"],"sources":["../../../src/components/TransactionDetails.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport ExpandLess from '@mui/icons-material/ExpandLess'\nimport ExpandMore from '@mui/icons-material/ExpandMore'\nimport LocalGasStationRounded from '@mui/icons-material/LocalGasStationRounded'\nimport type { CardProps } from '@mui/material'\nimport { Box, Collapse, Tooltip, Typography } from '@mui/material'\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { isRouteDone } from '../stores/routes/utils.js'\nimport { getAccumulatedFeeCostsBreakdown } from '../utils/fees.js'\nimport { formatTokenAmount, formatTokenPrice } from '../utils/format.js'\nimport { getPriceImpact } from '../utils/getPriceImpact.js'\nimport { Card } from './Card/Card.js'\nimport { CardIconButton } from './Card/CardIconButton.js'\nimport { FeeBreakdownTooltip } from './FeeBreakdownTooltip.js'\nimport { IconTypography } from './IconTypography.js'\nimport { TokenRate } from './TokenRate/TokenRate.js'\n\ninterface TransactionDetailsProps extends CardProps {\n route: RouteExtended\n}\n\nexport const TransactionDetails: React.FC<TransactionDetailsProps> = ({\n route,\n ...props\n}) => {\n const { t } = useTranslation()\n const { feeConfig, defaultUI } = useWidgetConfig()\n const [cardExpanded, setCardExpanded] = useState(\n defaultUI?.transactionDetailsExpanded ?? false\n )\n const { isGaslessStep } = useEthereumContext()\n\n const toggleCard = () => {\n setCardExpanded((cardExpanded) => !cardExpanded)\n }\n const { gasCosts, feeCosts, gasCostUSD, feeCostUSD, combinedFeesUSD } =\n getAccumulatedFeeCostsBreakdown(route)\n\n const priceImpact = getPriceImpact({\n fromAmount: BigInt(route.fromAmount),\n toAmount: BigInt(route.toAmount),\n fromToken: route.fromToken,\n toToken: route.toToken,\n })\n\n const feeCollectionStep = route.steps[0].includedSteps.find(\n (includedStep) => includedStep.tool === 'feeCollection'\n )\n\n let feeAmountUSD = 0\n let feePercentage = 0\n\n if (feeCollectionStep) {\n const estimatedFromAmount =\n BigInt(feeCollectionStep.estimate.fromAmount) -\n BigInt(feeCollectionStep.estimate.toAmount)\n\n feeAmountUSD = formatTokenPrice(\n estimatedFromAmount,\n feeCollectionStep.action.fromToken.priceUSD,\n feeCollectionStep.action.fromToken.decimals\n )\n\n feePercentage =\n feeCollectionStep.estimate.feeCosts?.reduce(\n (percentage, feeCost) =>\n percentage + Number.parseFloat(feeCost.percentage || '0'),\n 0\n ) ?? 0\n }\n\n const hasGaslessSupport = route.steps.every((step) => isGaslessStep?.(step))\n\n const showIntegratorFeeCollectionDetails =\n (feeAmountUSD || Number.isFinite(feeConfig?.fee)) && !hasGaslessSupport\n\n return (\n <Card selectionColor=\"secondary\" {...props}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 2,\n py: 1.75,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n alignItems: 'center',\n justifyContent: 'left',\n }}\n >\n <TokenRate route={route} />\n </Box>\n <Collapse timeout={100} in={!cardExpanded} mountOnEnter>\n <FeeBreakdownTooltip\n gasCosts={gasCosts}\n feeCosts={feeCosts}\n gasless={hasGaslessSupport}\n >\n <Box\n onClick={toggleCard}\n role=\"button\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1,\n cursor: 'pointer',\n }}\n >\n <IconTypography mr={0.5} fontSize={16}>\n <LocalGasStationRounded fontSize=\"inherit\" />\n </IconTypography>\n <Typography\n data-value={combinedFeesUSD}\n sx={{\n fontSize: 14,\n color: 'text.primary',\n fontWeight: 600,\n lineHeight: 1.429,\n }}\n >\n {!combinedFeesUSD\n ? t('main.fees.free')\n : t('format.currency', { value: combinedFeesUSD })}\n </Typography>\n </Box>\n </FeeBreakdownTooltip>\n </Collapse>\n <CardIconButton onClick={toggleCard} size=\"small\">\n {cardExpanded ? (\n <ExpandLess fontSize=\"inherit\" />\n ) : (\n <ExpandMore fontSize=\"inherit\" />\n )}\n </CardIconButton>\n </Box>\n <Collapse timeout={225} in={cardExpanded} mountOnEnter>\n <Box\n sx={{\n px: 2,\n pb: 2,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.fees.network')}</Typography>\n <FeeBreakdownTooltip\n gasCosts={gasCosts}\n gasless={hasGaslessSupport}\n >\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {!gasCostUSD\n ? t('main.fees.free')\n : t('format.currency', {\n value: gasCostUSD,\n })}\n </Typography>\n </FeeBreakdownTooltip>\n </Box>\n {feeCosts.length ? (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.fees.provider')}</Typography>\n <FeeBreakdownTooltip feeCosts={feeCosts}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.currency', {\n value: feeCostUSD,\n })}\n </Typography>\n </FeeBreakdownTooltip>\n </Box>\n ) : null}\n {showIntegratorFeeCollectionDetails ? (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">\n {feeConfig?.name || t('main.fees.defaultIntegrator')}\n {feeConfig?.showFeePercentage && (\n <> ({t('format.percent', { value: feePercentage })})</>\n )}\n </Typography>\n {feeConfig?.showFeeTooltip &&\n (feeConfig?.name || feeConfig?.feeTooltipComponent) ? (\n <Tooltip\n title={\n feeConfig?.feeTooltipComponent ||\n t('tooltip.feeCollection', { tool: feeConfig.name })\n }\n >\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.currency', {\n value: feeAmountUSD,\n })}\n </Typography>\n </Tooltip>\n ) : (\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n {t('format.currency', {\n value: feeAmountUSD,\n })}\n </Typography>\n )}\n </Box>\n ) : null}\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.priceImpact')}</Typography>\n <Tooltip title={t('tooltip.priceImpact')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.percent', {\n value: priceImpact,\n usePlusSign: true,\n })}\n </Typography>\n </Tooltip>\n </Box>\n {!isRouteDone(route) ? (\n <>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.maxSlippage')}</Typography>\n <Tooltip title={t('tooltip.slippage')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {route.steps[0].action.slippage\n ? t('format.percent', {\n value: route.steps[0].action.slippage,\n })\n : t('button.auto')}\n </Typography>\n </Tooltip>\n </Box>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n <Typography variant=\"body2\">{t('main.minReceived')}</Typography>\n <Tooltip title={t('tooltip.minReceived')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(route.toAmountMin),\n route.toToken.decimals\n ),\n })}{' '}\n {route.toToken.symbol}\n </Typography>\n </Tooltip>\n </Box>\n </>\n ) : null}\n </Box>\n </Collapse>\n </Card>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TransactionDetails.js","names":["Card"],"sources":["../../../src/components/TransactionDetails.tsx"],"sourcesContent":["import type { RouteExtended } from '@lifi/sdk'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport ExpandLess from '@mui/icons-material/ExpandLess'\nimport ExpandMore from '@mui/icons-material/ExpandMore'\nimport LocalGasStationRounded from '@mui/icons-material/LocalGasStationRounded'\nimport type { CardProps } from '@mui/material'\nimport { Box, Collapse, Tooltip, Typography } from '@mui/material'\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { isRouteDone } from '../stores/routes/utils.js'\nimport { getAccumulatedFeeCostsBreakdown } from '../utils/fees.js'\nimport { formatTokenAmount, formatTokenPrice } from '../utils/format.js'\nimport { getPriceImpact } from '../utils/getPriceImpact.js'\nimport { Card } from './Card/Card.js'\nimport { CardIconButton } from './Card/CardIconButton.js'\nimport { FeeBreakdownTooltip } from './FeeBreakdownTooltip.js'\nimport { IconTypography } from './IconTypography.js'\nimport { TokenRate } from './TokenRate/TokenRate.js'\n\ninterface TransactionDetailsProps extends CardProps {\n route: RouteExtended\n}\n\nexport const TransactionDetails: React.FC<TransactionDetailsProps> = ({\n route,\n ...props\n}) => {\n const { t } = useTranslation()\n const { feeConfig, defaultUI } = useWidgetConfig()\n const [cardExpanded, setCardExpanded] = useState(\n defaultUI?.transactionDetailsExpanded ?? false\n )\n const { isGaslessStep } = useEthereumContext()\n\n const toggleCard = () => {\n setCardExpanded((cardExpanded) => !cardExpanded)\n }\n const { gasCosts, feeCosts, gasCostUSD, feeCostUSD, combinedFeesUSD } =\n getAccumulatedFeeCostsBreakdown(route)\n\n const priceImpact = getPriceImpact({\n fromAmount: BigInt(route.fromAmount),\n toAmount: BigInt(route.toAmount),\n fromToken: route.fromToken,\n toToken: route.toToken,\n })\n\n const feeCollectionStep = route.steps[0].includedSteps.find(\n (includedStep) => includedStep.tool === 'feeCollection'\n )\n\n let feeAmountUSD = 0\n let feePercentage = 0\n\n if (feeCollectionStep) {\n const estimatedFromAmount =\n BigInt(feeCollectionStep.estimate.fromAmount) -\n BigInt(feeCollectionStep.estimate.toAmount)\n\n feeAmountUSD = formatTokenPrice(\n estimatedFromAmount,\n feeCollectionStep.action.fromToken.priceUSD,\n feeCollectionStep.action.fromToken.decimals\n )\n\n feePercentage =\n feeCollectionStep.estimate.feeCosts?.reduce(\n (percentage, feeCost) =>\n percentage + Number.parseFloat(feeCost.percentage || '0'),\n 0\n ) ?? 0\n }\n\n const hasGaslessSupport = route.steps.every((step) => isGaslessStep?.(step))\n\n const showIntegratorFeeCollectionDetails =\n (feeAmountUSD || Number.isFinite(feeConfig?.fee)) && !hasGaslessSupport\n\n return (\n <Card selectionColor=\"secondary\" {...props}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 2,\n py: 1.75,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n alignItems: 'center',\n justifyContent: 'left',\n }}\n >\n <TokenRate route={route} />\n </Box>\n <Collapse timeout={100} in={!cardExpanded} mountOnEnter>\n <FeeBreakdownTooltip\n gasCosts={gasCosts}\n feeCosts={feeCosts}\n gasless={hasGaslessSupport}\n >\n <Box\n onClick={toggleCard}\n role=\"button\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n px: 1,\n cursor: 'pointer',\n }}\n >\n <IconTypography component=\"span\" sx={{ mr: 0.5, fontSize: 16 }}>\n <LocalGasStationRounded fontSize=\"inherit\" />\n </IconTypography>\n <Typography\n data-value={combinedFeesUSD}\n sx={{\n fontSize: 14,\n color: 'text.primary',\n fontWeight: 600,\n lineHeight: 1.429,\n }}\n >\n {!combinedFeesUSD\n ? t('main.fees.free')\n : t('format.currency', { value: combinedFeesUSD })}\n </Typography>\n </Box>\n </FeeBreakdownTooltip>\n </Collapse>\n <CardIconButton onClick={toggleCard} size=\"small\">\n {cardExpanded ? (\n <ExpandLess fontSize=\"inherit\" />\n ) : (\n <ExpandMore fontSize=\"inherit\" />\n )}\n </CardIconButton>\n </Box>\n <Collapse timeout={225} in={cardExpanded} mountOnEnter>\n <Box\n sx={{\n px: 2,\n pb: 2,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.fees.network')}</Typography>\n <FeeBreakdownTooltip\n gasCosts={gasCosts}\n gasless={hasGaslessSupport}\n >\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {!gasCostUSD\n ? t('main.fees.free')\n : t('format.currency', {\n value: gasCostUSD,\n })}\n </Typography>\n </FeeBreakdownTooltip>\n </Box>\n {feeCosts.length ? (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.fees.provider')}</Typography>\n <FeeBreakdownTooltip feeCosts={feeCosts}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.currency', {\n value: feeCostUSD,\n })}\n </Typography>\n </FeeBreakdownTooltip>\n </Box>\n ) : null}\n {showIntegratorFeeCollectionDetails ? (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">\n {feeConfig?.name || t('main.fees.defaultIntegrator')}\n {feeConfig?.showFeePercentage && (\n <> ({t('format.percent', { value: feePercentage })})</>\n )}\n </Typography>\n {feeConfig?.showFeeTooltip &&\n (feeConfig?.name || feeConfig?.feeTooltipComponent) ? (\n <Tooltip\n title={\n feeConfig?.feeTooltipComponent ||\n t('tooltip.feeCollection', { tool: feeConfig.name })\n }\n >\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.currency', {\n value: feeAmountUSD,\n })}\n </Typography>\n </Tooltip>\n ) : (\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n {t('format.currency', {\n value: feeAmountUSD,\n })}\n </Typography>\n )}\n </Box>\n ) : null}\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.priceImpact')}</Typography>\n <Tooltip title={t('tooltip.priceImpact')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.percent', {\n value: priceImpact,\n usePlusSign: true,\n })}\n </Typography>\n </Tooltip>\n </Box>\n {!isRouteDone(route) ? (\n <>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n mb: 0.5,\n }}\n >\n <Typography variant=\"body2\">{t('main.maxSlippage')}</Typography>\n <Tooltip title={t('tooltip.slippage')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {route.steps[0].action.slippage\n ? t('format.percent', {\n value: route.steps[0].action.slippage,\n })\n : t('button.auto')}\n </Typography>\n </Tooltip>\n </Box>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n <Typography variant=\"body2\">{t('main.minReceived')}</Typography>\n <Tooltip title={t('tooltip.minReceived')}>\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 600, cursor: 'help' }}\n >\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(route.toAmountMin),\n route.toToken.decimals\n ),\n })}{' '}\n {route.toToken.symbol}\n </Typography>\n </Tooltip>\n </Box>\n </>\n ) : null}\n </Box>\n </Collapse>\n </Card>\n )\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.d.ts
2
2
  declare const name = "@lifi/widget";
3
- declare const version = "4.0.0-beta.14";
3
+ declare const version = "4.0.0-beta.17";
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.0.0-beta.14";
3
+ const version = "4.0.0-beta.17";
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.0.0-beta.14'\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.0.0-beta.17'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
@@ -4,11 +4,6 @@ import { useMutation } from "@tanstack/react-query";
4
4
  import { useChainTypeFromAddress } from "@lifi/widget-provider";
5
5
  import { useTranslation } from "react-i18next";
6
6
  //#region src/hooks/useAddressValidation.ts
7
- let AddressType = /* @__PURE__ */ function(AddressType) {
8
- AddressType[AddressType["Address"] = 0] = "Address";
9
- AddressType[AddressType["NameService"] = 1] = "NameService";
10
- return AddressType;
11
- }({});
12
7
  const useAddressValidation = () => {
13
8
  const { t } = useTranslation();
14
9
  const { getChainTypeFromAddress } = useChainTypeFromAddress();
@@ -19,7 +14,7 @@ const useAddressValidation = () => {
19
14
  const _chainType = getChainTypeFromAddress(value);
20
15
  if (_chainType) return {
21
16
  address: value,
22
- addressType: AddressType.Address,
17
+ addressType: 0,
23
18
  chainType: _chainType,
24
19
  isValid: true
25
20
  };
@@ -28,7 +23,7 @@ const useAddressValidation = () => {
28
23
  const _chainType = getChainTypeFromAddress(address);
29
24
  if (_chainType) return {
30
25
  address,
31
- addressType: AddressType.NameService,
26
+ addressType: 1,
32
27
  chainType: _chainType,
33
28
  isValid: true
34
29
  };
@@ -50,6 +45,6 @@ const useAddressValidation = () => {
50
45
  };
51
46
  };
52
47
  //#endregion
53
- export { AddressType, useAddressValidation };
48
+ export { useAddressValidation };
54
49
 
55
50
  //# sourceMappingURL=useAddressValidation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAddressValidation.js","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"sourcesContent":["import type { Chain, ChainType } from '@lifi/sdk'\nimport { getNameServiceAddress } from '@lifi/sdk'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useMutation } from '@tanstack/react-query'\nimport { useTranslation } from 'react-i18next'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\n\nexport enum AddressType {\n Address = 0,\n NameService = 1,\n}\n\ntype ValidationArgs = {\n value: string\n chainType?: ChainType\n chain?: Chain\n}\n\ntype ValidResponse = {\n address: string\n addressType: AddressType\n chainType: ChainType\n isValid: true\n}\n\ntype InvalidResponse = {\n error: string\n isValid: false\n}\n\nexport const useAddressValidation = (): {\n validateAddress: (\n args: ValidationArgs\n ) => Promise<ValidResponse | InvalidResponse>\n isValidating: boolean\n} => {\n const { t } = useTranslation()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n const sdkClient = useSDKClient()\n\n const { mutateAsync: validateAddress, isPending: isValidating } = useMutation(\n {\n mutationFn: async ({\n value,\n chainType,\n chain,\n }: ValidationArgs): Promise<ValidResponse | InvalidResponse> => {\n try {\n if (!value) {\n throw new Error()\n }\n\n const _chainType = getChainTypeFromAddress(value)\n if (_chainType) {\n return {\n address: value,\n addressType: AddressType.Address,\n chainType: _chainType,\n isValid: true,\n }\n }\n\n const address = await getNameServiceAddress(\n sdkClient,\n value,\n chainType\n )\n\n if (address) {\n const _chainType = getChainTypeFromAddress(address)\n if (_chainType) {\n return {\n address: address,\n addressType: AddressType.NameService,\n chainType: _chainType,\n isValid: true,\n }\n }\n }\n\n throw new Error()\n } catch (_) {\n return {\n isValid: false,\n error: t(\n 'error.title.walletAddressInvalid',\n chain?.name\n ? { context: 'chain', chainName: chain.name }\n : undefined\n ),\n }\n }\n },\n }\n )\n\n return {\n validateAddress,\n isValidating,\n }\n}\n"],"mappings":";;;;;;AAOA,IAAY,cAAL,yBAAA,aAAA;AACL,aAAA,YAAA,aAAA,KAAA;AACA,aAAA,YAAA,iBAAA,KAAA;;KACD;AAoBD,MAAa,6BAKR;CACH,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,4BAA4B,yBAAyB;CAC7D,MAAM,YAAY,cAAc;CAEhC,MAAM,EAAE,aAAa,iBAAiB,WAAW,iBAAiB,YAChE,EACE,YAAY,OAAO,EACjB,OACA,WACA,YAC8D;AAC9D,MAAI;AACF,OAAI,CAAC,MACH,OAAM,IAAI,OAAO;GAGnB,MAAM,aAAa,wBAAwB,MAAM;AACjD,OAAI,WACF,QAAO;IACL,SAAS;IACT,aAAa,YAAY;IACzB,WAAW;IACX,SAAS;IACV;GAGH,MAAM,UAAU,MAAM,sBACpB,WACA,OACA,UACD;AAED,OAAI,SAAS;IACX,MAAM,aAAa,wBAAwB,QAAQ;AACnD,QAAI,WACF,QAAO;KACI;KACT,aAAa,YAAY;KACzB,WAAW;KACX,SAAS;KACV;;AAIL,SAAM,IAAI,OAAO;WACV,GAAG;AACV,UAAO;IACL,SAAS;IACT,OAAO,EACL,oCACA,OAAO,OACH;KAAE,SAAS;KAAS,WAAW,MAAM;KAAM,GAC3C,KAAA,EACL;IACF;;IAGN,CACF;AAED,QAAO;EACL;EACA;EACD"}
1
+ {"version":3,"file":"useAddressValidation.js","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"sourcesContent":["import type { Chain, ChainType } from '@lifi/sdk'\nimport { getNameServiceAddress } from '@lifi/sdk'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useMutation } from '@tanstack/react-query'\nimport { useTranslation } from 'react-i18next'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\n\nexport enum AddressType {\n Address = 0,\n NameService = 1,\n}\n\ntype ValidationArgs = {\n value: string\n chainType?: ChainType\n chain?: Chain\n}\n\ntype ValidResponse = {\n address: string\n addressType: AddressType\n chainType: ChainType\n isValid: true\n}\n\ntype InvalidResponse = {\n error: string\n isValid: false\n}\n\nexport const useAddressValidation = (): {\n validateAddress: (\n args: ValidationArgs\n ) => Promise<ValidResponse | InvalidResponse>\n isValidating: boolean\n} => {\n const { t } = useTranslation()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n const sdkClient = useSDKClient()\n\n const { mutateAsync: validateAddress, isPending: isValidating } = useMutation(\n {\n mutationFn: async ({\n value,\n chainType,\n chain,\n }: ValidationArgs): Promise<ValidResponse | InvalidResponse> => {\n try {\n if (!value) {\n throw new Error()\n }\n\n const _chainType = getChainTypeFromAddress(value)\n if (_chainType) {\n return {\n address: value,\n addressType: AddressType.Address,\n chainType: _chainType,\n isValid: true,\n }\n }\n\n const address = await getNameServiceAddress(\n sdkClient,\n value,\n chainType\n )\n\n if (address) {\n const _chainType = getChainTypeFromAddress(address)\n if (_chainType) {\n return {\n address: address,\n addressType: AddressType.NameService,\n chainType: _chainType,\n isValid: true,\n }\n }\n }\n\n throw new Error()\n } catch (_) {\n return {\n isValid: false,\n error: t(\n 'error.title.walletAddressInvalid',\n chain?.name\n ? { context: 'chain', chainName: chain.name }\n : undefined\n ),\n }\n }\n },\n }\n )\n\n return {\n validateAddress,\n isValidating,\n }\n}\n"],"mappings":";;;;;;AA8BA,MAAa,6BAKR;CACH,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,4BAA4B,yBAAyB;CAC7D,MAAM,YAAY,cAAc;CAEhC,MAAM,EAAE,aAAa,iBAAiB,WAAW,iBAAiB,YAChE,EACE,YAAY,OAAO,EACjB,OACA,WACA,YAC8D;AAC9D,MAAI;AACF,OAAI,CAAC,MACH,OAAM,IAAI,OAAO;GAGnB,MAAM,aAAa,wBAAwB,MAAM;AACjD,OAAI,WACF,QAAO;IACL,SAAS;IACT,aAAA;IACA,WAAW;IACX,SAAS;IACV;GAGH,MAAM,UAAU,MAAM,sBACpB,WACA,OACA,UACD;AAED,OAAI,SAAS;IACX,MAAM,aAAa,wBAAwB,QAAQ;AACnD,QAAI,WACF,QAAO;KACI;KACT,aAAA;KACA,WAAW;KACX,SAAS;KACV;;AAIL,SAAM,IAAI,OAAO;WACV,GAAG;AACV,UAAO;IACL,SAAS;IACT,OAAO,EACL,oCACA,OAAO,OACH;KAAE,SAAS;KAAS,WAAW,MAAM;KAAM,GAC3C,KAAA,EACL;IACF;;IAGN,CACF;AAED,QAAO;EACL;EACA;EACD"}
@@ -10,7 +10,8 @@ const supportedChainTypes = [
10
10
  ChainType.EVM,
11
11
  ChainType.SVM,
12
12
  ChainType.UTXO,
13
- ChainType.MVM
13
+ ChainType.MVM,
14
+ ChainType.TVM
14
15
  ];
15
16
  const useAvailableChains = (chainTypes, widgetConfig) => {
16
17
  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]\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;CACX;AAED,MAAa,sBACX,YACA,iBAKG;CACH,MAAM,EAAE,QAAQ,gBAAgB,WAAW,sBACzC,iBAAiB;CACnB,MAAM,iBAAiB,cAAc;CAErC,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,aACH;AAEF,SAAO,aAAa;GAClB,GAAG,aAAa;GAChB,QAAQ,aAAa;GACrB,YAAY,aAAa,cAAc,QAAQ,SAAS;GACzD,CAAC;IACD,CAAC,aAAa,CAAC;CAGlB,MAAM,YAAY,cAAc,aAAa;CAC7C,MAAM,SAAS,cAAc,UAAU;CAEvC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GACR,YAAY,UAAU,UAAU;GAChC,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,CAAC,CAAC;GACH;EACD,SAAS,OAAO,EAAE,UAAU,GAAG,wBAAwB;GACrD,MAAM,mBAAmB,kBACvB,mBACC,WAAW,IAAI,IAAI,OAAO,CAC5B;GACD,MAAM,oBAAoB,oBAAoB,QAAQ,cACpD,qBAAqB,WAAW,iBAAiB,CAClD;GACD,MAAM,SAAS,kBAAkB;GACjC,MAAM,kBAAkB,MAAM,UAAU,QAAQ,EAC9C,YAAY,cAAc,mBAC3B,CAAC;AACF,UAAO,UAAU,gBAAgB;AACjC,UAAO;;EAET,iBAAiB;EACjB,WAAW;EACZ,CAAC;AAKF,iBAAgB;AACd,MAAI,QAAQ,CAAC,eACX,gBAAe,UAAU,KAAK;IAE/B;EAAC;EAAM;EAAgB;EAAe,CAAC;AAgB1C,QAAO;EACL,QAAQ;EACR,cAhBiC,aAChC,SAAkB,SAAsC,SAAS;AAChE,OAAI,CAAC,QACH;AAMF,UAJc,QAAQ,MAAM,UAAU,MAAM,OAAO,QAAQ;KAM7D,CAAC,KAAK,CACP;EAKC;EACD"}
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;CACX;AAED,MAAa,sBACX,YACA,iBAKG;CACH,MAAM,EAAE,QAAQ,gBAAgB,WAAW,sBACzC,iBAAiB;CACnB,MAAM,iBAAiB,cAAc;CAErC,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,aACH;AAEF,SAAO,aAAa;GAClB,GAAG,aAAa;GAChB,QAAQ,aAAa;GACrB,YAAY,aAAa,cAAc,QAAQ,SAAS;GACzD,CAAC;IACD,CAAC,aAAa,CAAC;CAGlB,MAAM,YAAY,cAAc,aAAa;CAC7C,MAAM,SAAS,cAAc,UAAU;CAEvC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GACR,YAAY,UAAU,UAAU;GAChC,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,CAAC,CAAC;GACH;EACD,SAAS,OAAO,EAAE,UAAU,GAAG,wBAAwB;GACrD,MAAM,mBAAmB,kBACvB,mBACC,WAAW,IAAI,IAAI,OAAO,CAC5B;GACD,MAAM,oBAAoB,oBAAoB,QAAQ,cACpD,qBAAqB,WAAW,iBAAiB,CAClD;GACD,MAAM,SAAS,kBAAkB;GACjC,MAAM,kBAAkB,MAAM,UAAU,QAAQ,EAC9C,YAAY,cAAc,mBAC3B,CAAC;AACF,UAAO,UAAU,gBAAgB;AACjC,UAAO;;EAET,iBAAiB;EACjB,WAAW;EACZ,CAAC;AAKF,iBAAgB;AACd,MAAI,QAAQ,CAAC,eACX,gBAAe,UAAU,KAAK;IAE/B;EAAC;EAAM;EAAgB;EAAe,CAAC;AAgB1C,QAAO;EACL,QAAQ;EACR,cAhBiC,aAChC,SAAkB,SAAsC,SAAS;AAChE,OAAI,CAAC,QACH;AAMF,UAJc,QAAQ,MAAM,UAAU,MAAM,OAAO,QAAQ;KAM7D,CAAC,KAAK,CACP;EAKC;EACD"}
@@ -1,11 +1,11 @@
1
1
  import { useWidgetEvents } from "./useWidgetEvents.js";
2
- import { WidgetEvent } from "../types/events.js";
2
+ import "../types/events.js";
3
3
  //#region src/hooks/useContactSupport.ts
4
4
  const useContactSupport = (supportId) => {
5
5
  const widgetEvents = useWidgetEvents();
6
6
  const handleContactSupport = () => {
7
- if (!widgetEvents.all.has(WidgetEvent.ContactSupport)) window.open("https://help.li.fi", "_blank", "nofollow noreferrer");
8
- else widgetEvents.emit(WidgetEvent.ContactSupport, { supportId });
7
+ if (!widgetEvents.all.has("contactSupport")) window.open("https://help.li.fi", "_blank", "nofollow noreferrer");
8
+ else widgetEvents.emit("contactSupport", { supportId });
9
9
  };
10
10
  return handleContactSupport;
11
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useContactSupport.js","names":[],"sources":["../../../src/hooks/useContactSupport.ts"],"sourcesContent":["import { WidgetEvent } from '../types/events.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\nexport const useContactSupport = (supportId?: string): (() => void) => {\n const widgetEvents = useWidgetEvents()\n\n const handleContactSupport = () => {\n if (!widgetEvents.all.has(WidgetEvent.ContactSupport)) {\n window.open('https://help.li.fi', '_blank', 'nofollow noreferrer')\n } else {\n widgetEvents.emit(WidgetEvent.ContactSupport, { supportId })\n }\n }\n\n return handleContactSupport\n}\n"],"mappings":";;;AAGA,MAAa,qBAAqB,cAAqC;CACrE,MAAM,eAAe,iBAAiB;CAEtC,MAAM,6BAA6B;AACjC,MAAI,CAAC,aAAa,IAAI,IAAI,YAAY,eAAe,CACnD,QAAO,KAAK,sBAAsB,UAAU,sBAAsB;MAElE,cAAa,KAAK,YAAY,gBAAgB,EAAE,WAAW,CAAC;;AAIhE,QAAO"}
1
+ {"version":3,"file":"useContactSupport.js","names":[],"sources":["../../../src/hooks/useContactSupport.ts"],"sourcesContent":["import { WidgetEvent } from '../types/events.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\nexport const useContactSupport = (supportId?: string): (() => void) => {\n const widgetEvents = useWidgetEvents()\n\n const handleContactSupport = () => {\n if (!widgetEvents.all.has(WidgetEvent.ContactSupport)) {\n window.open('https://help.li.fi', '_blank', 'nofollow noreferrer')\n } else {\n widgetEvents.emit(WidgetEvent.ContactSupport, { supportId })\n }\n }\n\n return handleContactSupport\n}\n"],"mappings":";;;AAGA,MAAa,qBAAqB,cAAqC;CACrE,MAAM,eAAe,iBAAiB;CAEtC,MAAM,6BAA6B;AACjC,MAAI,CAAC,aAAa,IAAI,IAAA,iBAA+B,CACnD,QAAO,KAAK,sBAAsB,UAAU,sBAAsB;MAElE,cAAa,KAAA,kBAAiC,EAAE,WAAW,CAAC;;AAIhE,QAAO"}
@@ -4,19 +4,30 @@ import { useAvailableChains } from "./useAvailableChains.js";
4
4
  import { ChainId, ChainType, isHex } from "@lifi/sdk";
5
5
  //#region src/hooks/useExplorer.ts
6
6
  const sanitiseBaseUrl = (baseUrl) => baseUrl.trim().replace(/\/+$/, "");
7
+ const explorerPathOverrides = {
8
+ [ChainId.SUI]: {
9
+ txPath: "txblock",
10
+ addressPath: "coin"
11
+ },
12
+ [ChainType.TVM]: {
13
+ txPath: "#/transaction",
14
+ addressPath: "#/address"
15
+ }
16
+ };
7
17
  const useExplorer = () => {
8
18
  const { explorerUrls } = useWidgetConfig();
9
19
  const { getChainById } = useAvailableChains();
10
20
  const getExplorerConfig = (chain) => {
11
21
  const resolvedChain = Number.isFinite(chain) ? getChainById(chain) : chain;
12
22
  const explorerUrl = (resolvedChain ? explorerUrls?.[resolvedChain.id]?.[0] ?? resolvedChain.metamask.blockExplorerUrls[0] : explorerUrls?.internal?.[0]) || "https://scan.li.fi";
13
- const url = typeof explorerUrl === "string" ? explorerUrl : explorerUrl.url;
14
- const defaultTxPath = resolvedChain?.id === ChainId.SUI ? "txblock" : "tx";
15
- const defaultAddressPath = resolvedChain?.id === ChainId.SUI ? "coin" : "address";
23
+ const baseUrl = typeof explorerUrl === "string" ? explorerUrl : explorerUrl.url;
24
+ const overrides = explorerPathOverrides[resolvedChain?.id] ?? explorerPathOverrides[resolvedChain?.chainType];
25
+ const defaultTxPath = overrides?.txPath ?? "tx";
26
+ const defaultAddressPath = overrides?.addressPath ?? "address";
16
27
  const txPath = typeof explorerUrl === "string" ? defaultTxPath : explorerUrl.txPath || defaultTxPath;
17
28
  const addressPath = typeof explorerUrl === "string" ? defaultAddressPath : explorerUrl.addressPath || defaultAddressPath;
18
29
  return {
19
- url: sanitiseBaseUrl(url),
30
+ url: sanitiseBaseUrl(baseUrl),
20
31
  txPath,
21
32
  addressPath,
22
33
  resolvedChain
@@ -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 { 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\ntype TransactionLinkProps = { chain?: Chain | number } & (\n | {\n txHash: string\n txLink?: never\n }\n | {\n txHash?: never\n txLink: string\n }\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 = (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 url = typeof explorerUrl === 'string' ? explorerUrl : explorerUrl.url\n\n const defaultTxPath = resolvedChain?.id === ChainId.SUI ? 'txblock' : 'tx'\n const defaultAddressPath =\n resolvedChain?.id === ChainId.SUI ? 'coin' : '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(url),\n txPath,\n addressPath,\n resolvedChain,\n }\n }\n\n const getTransactionLink = ({\n txHash,\n txLink,\n chain,\n }: TransactionLinkProps): string | undefined => {\n if (!txHash) {\n return txLink\n }\n\n const config = getExplorerConfig(chain)\n\n // For EVM chains, validate the transaction hash as some relayers return custom task hashes that are not visible on-chain\n if (config.resolvedChain?.chainType === ChainType.EVM) {\n if (!isHex(txHash, { strict: true })) {\n return undefined\n }\n }\n\n return `${config.url}/${config.txPath}/${txHash}`\n }\n\n const getAddressLink = (address: string, chain?: Chain | number) => {\n const config = getExplorerConfig(chain)\n return `${config.url}/${config.addressPath}/${address}`\n }\n\n return {\n getTransactionLink,\n getAddressLink,\n }\n}\n"],"mappings":";;;;;AAMA,MAAM,mBAAmB,YAAoB,QAAQ,MAAM,CAAC,QAAQ,QAAQ,GAAG;AAa/E,MAAa,oBAGR;CACH,MAAM,EAAE,iBAAiB,iBAAiB;CAC1C,MAAM,EAAE,iBAAiB,oBAAoB;CAE7C,MAAM,qBAAqB,UAA2B;EACpD,MAAM,gBAAgB,OAAO,SAAS,MAAM,GACxC,aAAa,MAAgB,GAC5B;EAEL,MAAM,eACH,gBACI,eAAe,cAAc,MAAM,MACpC,cAAc,SAAS,kBAAkB,KACzC,cAAc,WAAW,OAAA;EAE/B,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc,YAAY;EAExE,MAAM,gBAAgB,eAAe,OAAO,QAAQ,MAAM,YAAY;EACtE,MAAM,qBACJ,eAAe,OAAO,QAAQ,MAAM,SAAS;EAC/C,MAAM,SACJ,OAAO,gBAAgB,WACnB,gBACA,YAAY,UAAU;EAC5B,MAAM,cACJ,OAAO,gBAAgB,WACnB,qBACA,YAAY,eAAe;AAEjC,SAAO;GACL,KAAK,gBAAgB,IAAI;GACzB;GACA;GACA;GACD;;CAGH,MAAM,sBAAsB,EAC1B,QACA,QACA,YAC8C;AAC9C,MAAI,CAAC,OACH,QAAO;EAGT,MAAM,SAAS,kBAAkB,MAAM;AAGvC,MAAI,OAAO,eAAe,cAAc,UAAU;OAC5C,CAAC,MAAM,QAAQ,EAAE,QAAQ,MAAM,CAAC,CAClC;;AAIJ,SAAO,GAAG,OAAO,IAAI,GAAG,OAAO,OAAO,GAAG;;CAG3C,MAAM,kBAAkB,SAAiB,UAA2B;EAClE,MAAM,SAAS,kBAAkB,MAAM;AACvC,SAAO,GAAG,OAAO,IAAI,GAAG,OAAO,YAAY,GAAG;;AAGhD,QAAO;EACL;EACA;EACD"}
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 { 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 [ChainType.TVM]: { txPath: '#/transaction', addressPath: '#/address' },\n}\n\ntype TransactionLinkProps = { chain?: Chain | number } & (\n | {\n txHash: string\n txLink?: never\n }\n | {\n txHash?: never\n txLink: string\n }\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 = (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 }\n }\n\n const getTransactionLink = ({\n txHash,\n txLink,\n chain,\n }: TransactionLinkProps): string | undefined => {\n if (!txHash) {\n return txLink\n }\n\n const config = getExplorerConfig(chain)\n\n // For EVM chains, validate the transaction hash as some relayers return custom task hashes that are not visible on-chain\n if (config.resolvedChain?.chainType === ChainType.EVM) {\n if (!isHex(txHash, { strict: true })) {\n return undefined\n }\n }\n\n return `${config.url}/${config.txPath}/${txHash}`\n }\n\n const getAddressLink = (address: string, chain?: Chain | number) => {\n const config = getExplorerConfig(chain)\n return `${config.url}/${config.addressPath}/${address}`\n }\n\n return {\n getTransactionLink,\n getAddressLink,\n }\n}\n"],"mappings":";;;;;AAMA,MAAM,mBAAmB,YAAoB,QAAQ,MAAM,CAAC,QAAQ,QAAQ,GAAG;AAE/E,MAAM,wBAEF;EACD,QAAQ,MAAM;EAAE,QAAQ;EAAW,aAAa;EAAQ;EACxD,UAAU,MAAM;EAAE,QAAQ;EAAiB,aAAa;EAAa;CACvE;AAaD,MAAa,oBAGR;CACH,MAAM,EAAE,iBAAiB,iBAAiB;CAC1C,MAAM,EAAE,iBAAiB,oBAAoB;CAE7C,MAAM,qBAAqB,UAA2B;EACpD,MAAM,gBAAgB,OAAO,SAAS,MAAM,GACxC,aAAa,MAAgB,GAC5B;EAEL,MAAM,eACH,gBACI,eAAe,cAAc,MAAM,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;AAEjC,SAAO;GACL,KAAK,gBAAgB,QAAQ;GAC7B;GACA;GACA;GACD;;CAGH,MAAM,sBAAsB,EAC1B,QACA,QACA,YAC8C;AAC9C,MAAI,CAAC,OACH,QAAO;EAGT,MAAM,SAAS,kBAAkB,MAAM;AAGvC,MAAI,OAAO,eAAe,cAAc,UAAU;OAC5C,CAAC,MAAM,QAAQ,EAAE,QAAQ,MAAM,CAAC,CAClC;;AAIJ,SAAO,GAAG,OAAO,IAAI,GAAG,OAAO,OAAO,GAAG;;CAG3C,MAAM,kBAAkB,SAAiB,UAA2B;EAClE,MAAM,SAAS,kBAAkB,MAAM;AACvC,SAAO,GAAG,OAAO,IAAI,GAAG,OAAO,YAAY,GAAG;;AAGhD,QAAO;EACL;EACA;EACD"}
@@ -1,5 +1,5 @@
1
1
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
2
- import { HiddenUI } from "../types/widget.js";
2
+ import "../types/widget.js";
3
3
  import { useSDKClient } from "../providers/SDKClientProvider.js";
4
4
  import { getQueryKey } from "../utils/queries.js";
5
5
  import { useAvailableChains } from "./useAvailableChains.js";
@@ -28,7 +28,7 @@ const useGasRecommendation = (toChainId, fromChain, fromToken) => {
28
28
  fromToken
29
29
  }, { signal });
30
30
  },
31
- enabled: (checkRecommendationLiFuel || checkRecommendationMaxButton) && !hiddenUI?.includes(HiddenUI.GasRefuelMessage),
31
+ enabled: (checkRecommendationLiFuel || checkRecommendationMaxButton) && !hiddenUI?.includes("gasRefuelMessage"),
32
32
  refetchInterval,
33
33
  staleTime: refetchInterval
34
34
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useGasRecommendation.js","names":[],"sources":["../../../src/hooks/useGasRecommendation.ts"],"sourcesContent":["import { type ChainId, getGasRecommendation } from '@lifi/sdk'\nimport type { UseQueryResult } from '@tanstack/react-query'\nimport { useQuery } from '@tanstack/react-query'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\nconst refetchInterval = 60_000\n\nexport const useGasRecommendation = (\n toChainId?: ChainId,\n fromChain?: ChainId,\n fromToken?: string\n): UseQueryResult<Awaited<ReturnType<typeof getGasRecommendation>> | null> => {\n const { chains } = useAvailableChains()\n const { keyPrefix, hiddenUI } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const checkRecommendationLiFuel =\n Boolean(toChainId) &&\n Boolean(fromChain) &&\n Boolean(fromToken) &&\n Boolean(chains?.length)\n\n const checkRecommendationMaxButton =\n Boolean(toChainId) && !fromChain && !fromToken && Boolean(chains?.length)\n\n return useQuery({\n queryKey: [\n getQueryKey('gas-recommendation', keyPrefix),\n toChainId,\n fromChain,\n fromToken,\n ],\n queryFn: async ({\n queryKey: [_, toChainId, fromChain, fromToken],\n signal,\n }) => {\n if (!chains?.some((chain) => chain.id === toChainId)) {\n return null\n }\n const gasRecommendation = await getGasRecommendation(\n sdkClient,\n {\n chainId: toChainId as ChainId,\n fromChain: fromChain as ChainId,\n fromToken: fromToken as string,\n },\n { signal }\n )\n return gasRecommendation\n },\n enabled:\n (checkRecommendationLiFuel || checkRecommendationMaxButton) &&\n !hiddenUI?.includes(HiddenUI.GasRefuelMessage),\n refetchInterval,\n staleTime: refetchInterval,\n })\n}\n"],"mappings":";;;;;;;;AASA,MAAM,kBAAkB;AAExB,MAAa,wBACX,WACA,WACA,cAC4E;CAC5E,MAAM,EAAE,WAAW,oBAAoB;CACvC,MAAM,EAAE,WAAW,aAAa,iBAAiB;CACjD,MAAM,YAAY,cAAc;CAEhC,MAAM,4BACJ,QAAQ,UAAU,IAClB,QAAQ,UAAU,IAClB,QAAQ,UAAU,IAClB,QAAQ,QAAQ,OAAO;CAEzB,MAAM,+BACJ,QAAQ,UAAU,IAAI,CAAC,aAAa,CAAC,aAAa,QAAQ,QAAQ,OAAO;AAE3E,QAAO,SAAS;EACd,UAAU;GACR,YAAY,sBAAsB,UAAU;GAC5C;GACA;GACA;GACD;EACD,SAAS,OAAO,EACd,UAAU,CAAC,GAAG,WAAW,WAAW,YACpC,aACI;AACJ,OAAI,CAAC,QAAQ,MAAM,UAAU,MAAM,OAAO,UAAU,CAClD,QAAO;AAWT,UAT0B,MAAM,qBAC9B,WACA;IACE,SAAS;IACE;IACA;IACZ,EACD,EAAE,QAAQ,CACX;;EAGH,UACG,6BAA6B,iCAC9B,CAAC,UAAU,SAAS,SAAS,iBAAiB;EAChD;EACA,WAAW;EACZ,CAAC"}
1
+ {"version":3,"file":"useGasRecommendation.js","names":[],"sources":["../../../src/hooks/useGasRecommendation.ts"],"sourcesContent":["import { type ChainId, getGasRecommendation } from '@lifi/sdk'\nimport type { UseQueryResult } from '@tanstack/react-query'\nimport { useQuery } from '@tanstack/react-query'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\nconst refetchInterval = 60_000\n\nexport const useGasRecommendation = (\n toChainId?: ChainId,\n fromChain?: ChainId,\n fromToken?: string\n): UseQueryResult<Awaited<ReturnType<typeof getGasRecommendation>> | null> => {\n const { chains } = useAvailableChains()\n const { keyPrefix, hiddenUI } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const checkRecommendationLiFuel =\n Boolean(toChainId) &&\n Boolean(fromChain) &&\n Boolean(fromToken) &&\n Boolean(chains?.length)\n\n const checkRecommendationMaxButton =\n Boolean(toChainId) && !fromChain && !fromToken && Boolean(chains?.length)\n\n return useQuery({\n queryKey: [\n getQueryKey('gas-recommendation', keyPrefix),\n toChainId,\n fromChain,\n fromToken,\n ],\n queryFn: async ({\n queryKey: [_, toChainId, fromChain, fromToken],\n signal,\n }) => {\n if (!chains?.some((chain) => chain.id === toChainId)) {\n return null\n }\n const gasRecommendation = await getGasRecommendation(\n sdkClient,\n {\n chainId: toChainId as ChainId,\n fromChain: fromChain as ChainId,\n fromToken: fromToken as string,\n },\n { signal }\n )\n return gasRecommendation\n },\n enabled:\n (checkRecommendationLiFuel || checkRecommendationMaxButton) &&\n !hiddenUI?.includes(HiddenUI.GasRefuelMessage),\n refetchInterval,\n staleTime: refetchInterval,\n })\n}\n"],"mappings":";;;;;;;;AASA,MAAM,kBAAkB;AAExB,MAAa,wBACX,WACA,WACA,cAC4E;CAC5E,MAAM,EAAE,WAAW,oBAAoB;CACvC,MAAM,EAAE,WAAW,aAAa,iBAAiB;CACjD,MAAM,YAAY,cAAc;CAEhC,MAAM,4BACJ,QAAQ,UAAU,IAClB,QAAQ,UAAU,IAClB,QAAQ,UAAU,IAClB,QAAQ,QAAQ,OAAO;CAEzB,MAAM,+BACJ,QAAQ,UAAU,IAAI,CAAC,aAAa,CAAC,aAAa,QAAQ,QAAQ,OAAO;AAE3E,QAAO,SAAS;EACd,UAAU;GACR,YAAY,sBAAsB,UAAU;GAC5C;GACA;GACA;GACD;EACD,SAAS,OAAO,EACd,UAAU,CAAC,GAAG,WAAW,WAAW,YACpC,aACI;AACJ,OAAI,CAAC,QAAQ,MAAM,UAAU,MAAM,OAAO,UAAU,CAClD,QAAO;AAWT,UAT0B,MAAM,qBAC9B,WACA;IACE,SAAS;IACE;IACA;IACZ,EACD,EAAE,QAAQ,CACX;;EAGH,UACG,6BAA6B,iCAC9B,CAAC,UAAU,SAAA,mBAAmC;EAChD;EACA,WAAW;EACZ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
2
- import { HiddenUI } from "../types/widget.js";
2
+ import "../types/widget.js";
3
3
  import { useFieldValues } from "../stores/form/useFieldValues.js";
4
4
  import { useAvailableChains } from "./useAvailableChains.js";
5
5
  import { useGasRecommendation } from "./useGasRecommendation.js";
@@ -23,7 +23,7 @@ const useGasRefuel = () => {
23
23
  const isToAddressSatisfied = effectiveToAddress && !isToContractAddress;
24
24
  return {
25
25
  enabled: useMemo(() => {
26
- if (fromChainId === toChainId || !gasRecommendation?.available || !gasRecommendation?.recommended || !destinationNativeToken || !isChainTypeSatisfied || !isToAddressSatisfied || hiddenUI?.includes(HiddenUI.GasRefuelMessage)) return false;
26
+ if (fromChainId === toChainId || !gasRecommendation?.available || !gasRecommendation?.recommended || !destinationNativeToken || !isChainTypeSatisfied || !isToAddressSatisfied || hiddenUI?.includes("gasRefuelMessage")) return false;
27
27
  return (destinationNativeToken.amount ?? 0n) < BigInt(gasRecommendation.recommended.amount) / 2n;
28
28
  }, [
29
29
  fromChainId,
@@ -1 +1 @@
1
- {"version":3,"file":"useGasRefuel.js","names":[],"sources":["../../../src/hooks/useGasRefuel.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useGasRecommendation } from './useGasRecommendation.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { useTokenBalance } from './useTokenBalance.js'\n\nexport const useGasRefuel = (): {\n enabled: boolean\n availble: boolean | undefined\n isLoading: boolean\n chain: ExtendedChain | undefined\n fromAmount: string | undefined\n} => {\n const { getChainById } = useAvailableChains()\n const { hiddenUI } = useWidgetConfig()\n const [fromChainId, fromTokenAddress, toChainId, toAddress] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toAddress'\n )\n\n const toChain = getChainById(toChainId)\n const fromChain = getChainById(fromChainId)\n\n const { account: toAccount } = useAccount({ chainType: toChain?.chainType })\n\n const effectiveToAddress = toAddress || toAccount?.address\n\n const { isContractAddress: isToContractAddress } = useIsContractAddress(\n effectiveToAddress,\n toChainId,\n toChain?.chainType\n )\n\n const { token: destinationNativeToken } = useTokenBalance(\n effectiveToAddress,\n toChainId ? toChain?.nativeToken : undefined\n )\n\n const { data: gasRecommendation, isLoading } = useGasRecommendation(\n toChainId,\n fromChainId,\n fromTokenAddress\n )\n\n // When we bridge between ecosystems we need to be sure toAddress is set\n const isChainTypeSatisfied =\n fromChain?.chainType !== toChain?.chainType ? Boolean(toAddress) : true\n\n // We should not refuel to the contract address\n const isToAddressSatisfied = effectiveToAddress && !isToContractAddress\n\n const enabled = useMemo(() => {\n if (\n // Same chain refuel is not allowed since users need gas on source chain to initiate transaction\n // We allow refuel when bridging to native token since bridging routes may require gas for destination swaps\n fromChainId === toChainId ||\n !gasRecommendation?.available ||\n !gasRecommendation?.recommended ||\n !destinationNativeToken ||\n !isChainTypeSatisfied ||\n !isToAddressSatisfied ||\n hiddenUI?.includes(HiddenUI.GasRefuelMessage)\n ) {\n return false\n }\n const tokenBalance = destinationNativeToken.amount ?? 0n\n\n // Check if the user balance < 50% of the recommended amount\n const recommendedAmount = BigInt(gasRecommendation.recommended.amount) / 2n\n\n const insufficientGas = tokenBalance < recommendedAmount\n return insufficientGas\n }, [\n fromChainId,\n gasRecommendation,\n isChainTypeSatisfied,\n isToAddressSatisfied,\n destinationNativeToken,\n toChainId,\n hiddenUI,\n ])\n\n return {\n enabled: enabled,\n availble: gasRecommendation?.available,\n isLoading: isLoading,\n chain: toChain,\n fromAmount: gasRecommendation?.available\n ? gasRecommendation.fromAmount\n : undefined,\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAa,qBAMR;CACH,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,MAAM,EAAE,aAAa,iBAAiB;CACtC,MAAM,CAAC,aAAa,kBAAkB,WAAW,aAAa,eAC5D,aACA,aACA,WACA,YACD;CAED,MAAM,UAAU,aAAa,UAAU;CACvC,MAAM,YAAY,aAAa,YAAY;CAE3C,MAAM,EAAE,SAAS,cAAc,WAAW,EAAE,WAAW,SAAS,WAAW,CAAC;CAE5E,MAAM,qBAAqB,aAAa,WAAW;CAEnD,MAAM,EAAE,mBAAmB,wBAAwB,qBACjD,oBACA,WACA,SAAS,UACV;CAED,MAAM,EAAE,OAAO,2BAA2B,gBACxC,oBACA,YAAY,SAAS,cAAc,KAAA,EACpC;CAED,MAAM,EAAE,MAAM,mBAAmB,cAAc,qBAC7C,WACA,aACA,iBACD;CAGD,MAAM,uBACJ,WAAW,cAAc,SAAS,YAAY,QAAQ,UAAU,GAAG;CAGrE,MAAM,uBAAuB,sBAAsB,CAAC;AAiCpD,QAAO;EACL,SAhCc,cAAc;AAC5B,OAGE,gBAAgB,aAChB,CAAC,mBAAmB,aACpB,CAAC,mBAAmB,eACpB,CAAC,0BACD,CAAC,wBACD,CAAC,wBACD,UAAU,SAAS,SAAS,iBAAiB,CAE7C,QAAO;AAQT,WANqB,uBAAuB,UAAU,MAG5B,OAAO,kBAAkB,YAAY,OAAO,GAAG;KAIxE;GACD;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EAIA,UAAU,mBAAmB;EAClB;EACX,OAAO;EACP,YAAY,mBAAmB,YAC3B,kBAAkB,aAClB,KAAA;EACL"}
1
+ {"version":3,"file":"useGasRefuel.js","names":[],"sources":["../../../src/hooks/useGasRefuel.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useGasRecommendation } from './useGasRecommendation.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { useTokenBalance } from './useTokenBalance.js'\n\nexport const useGasRefuel = (): {\n enabled: boolean\n availble: boolean | undefined\n isLoading: boolean\n chain: ExtendedChain | undefined\n fromAmount: string | undefined\n} => {\n const { getChainById } = useAvailableChains()\n const { hiddenUI } = useWidgetConfig()\n const [fromChainId, fromTokenAddress, toChainId, toAddress] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toAddress'\n )\n\n const toChain = getChainById(toChainId)\n const fromChain = getChainById(fromChainId)\n\n const { account: toAccount } = useAccount({ chainType: toChain?.chainType })\n\n const effectiveToAddress = toAddress || toAccount?.address\n\n const { isContractAddress: isToContractAddress } = useIsContractAddress(\n effectiveToAddress,\n toChainId,\n toChain?.chainType\n )\n\n const { token: destinationNativeToken } = useTokenBalance(\n effectiveToAddress,\n toChainId ? toChain?.nativeToken : undefined\n )\n\n const { data: gasRecommendation, isLoading } = useGasRecommendation(\n toChainId,\n fromChainId,\n fromTokenAddress\n )\n\n // When we bridge between ecosystems we need to be sure toAddress is set\n const isChainTypeSatisfied =\n fromChain?.chainType !== toChain?.chainType ? Boolean(toAddress) : true\n\n // We should not refuel to the contract address\n const isToAddressSatisfied = effectiveToAddress && !isToContractAddress\n\n const enabled = useMemo(() => {\n if (\n // Same chain refuel is not allowed since users need gas on source chain to initiate transaction\n // We allow refuel when bridging to native token since bridging routes may require gas for destination swaps\n fromChainId === toChainId ||\n !gasRecommendation?.available ||\n !gasRecommendation?.recommended ||\n !destinationNativeToken ||\n !isChainTypeSatisfied ||\n !isToAddressSatisfied ||\n hiddenUI?.includes(HiddenUI.GasRefuelMessage)\n ) {\n return false\n }\n const tokenBalance = destinationNativeToken.amount ?? 0n\n\n // Check if the user balance < 50% of the recommended amount\n const recommendedAmount = BigInt(gasRecommendation.recommended.amount) / 2n\n\n const insufficientGas = tokenBalance < recommendedAmount\n return insufficientGas\n }, [\n fromChainId,\n gasRecommendation,\n isChainTypeSatisfied,\n isToAddressSatisfied,\n destinationNativeToken,\n toChainId,\n hiddenUI,\n ])\n\n return {\n enabled: enabled,\n availble: gasRecommendation?.available,\n isLoading: isLoading,\n chain: toChain,\n fromAmount: gasRecommendation?.available\n ? gasRecommendation.fromAmount\n : undefined,\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAa,qBAMR;CACH,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,MAAM,EAAE,aAAa,iBAAiB;CACtC,MAAM,CAAC,aAAa,kBAAkB,WAAW,aAAa,eAC5D,aACA,aACA,WACA,YACD;CAED,MAAM,UAAU,aAAa,UAAU;CACvC,MAAM,YAAY,aAAa,YAAY;CAE3C,MAAM,EAAE,SAAS,cAAc,WAAW,EAAE,WAAW,SAAS,WAAW,CAAC;CAE5E,MAAM,qBAAqB,aAAa,WAAW;CAEnD,MAAM,EAAE,mBAAmB,wBAAwB,qBACjD,oBACA,WACA,SAAS,UACV;CAED,MAAM,EAAE,OAAO,2BAA2B,gBACxC,oBACA,YAAY,SAAS,cAAc,KAAA,EACpC;CAED,MAAM,EAAE,MAAM,mBAAmB,cAAc,qBAC7C,WACA,aACA,iBACD;CAGD,MAAM,uBACJ,WAAW,cAAc,SAAS,YAAY,QAAQ,UAAU,GAAG;CAGrE,MAAM,uBAAuB,sBAAsB,CAAC;AAiCpD,QAAO;EACL,SAhCc,cAAc;AAC5B,OAGE,gBAAgB,aAChB,CAAC,mBAAmB,aACpB,CAAC,mBAAmB,eACpB,CAAC,0BACD,CAAC,wBACD,CAAC,wBACD,UAAU,SAAA,mBAAmC,CAE7C,QAAO;AAQT,WANqB,uBAAuB,UAAU,MAG5B,OAAO,kBAAkB,YAAY,OAAO,GAAG;KAIxE;GACD;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EAIA,UAAU,mBAAmB;EAClB;EACX,OAAO;EACP,YAAY,mBAAmB,YAC3B,kBAAkB,aAClB,KAAA;EACL"}
@@ -1,5 +1,5 @@
1
1
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
2
- import { HiddenUI } from "../types/widget.js";
2
+ import "../types/widget.js";
3
3
  import { useSDKClient } from "../providers/SDKClientProvider.js";
4
4
  import { getQueryKey } from "../utils/queries.js";
5
5
  import { useAvailableChains } from "./useAvailableChains.js";
@@ -90,7 +90,7 @@ const useGasSufficiency = (route) => {
90
90
  });
91
91
  return Object.values(gasCosts).filter((gasCost) => gasCost.insufficient);
92
92
  },
93
- enabled: Boolean(!isContractAddress && !isContractAddressLoading && relevantAccounts.length > 0 && route && !hiddenUI?.includes(HiddenUI.InsufficientGasMessage)),
93
+ enabled: Boolean(!isContractAddress && !isContractAddressLoading && relevantAccounts.length > 0 && route && !hiddenUI?.includes("insufficientGasMessage")),
94
94
  refetchInterval,
95
95
  staleTime: refetchInterval
96
96
  });
@@ -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 { HiddenUI } from '../types/widget.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 || 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?.includes(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 { HiddenUI } from '../types/widget.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 || 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?.includes(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,5 +1,5 @@
1
1
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
2
- import { ExpansionType, HiddenUI } from "../types/widget.js";
2
+ import "../types/widget.js";
3
3
  import { navigationRoutes } from "../utils/navigationRoutes.js";
4
4
  import { useSwapOnly } from "./useSwapOnly.js";
5
5
  import { useLocation } from "@tanstack/react-router";
@@ -8,8 +8,8 @@ const useHasChainExpansion = () => {
8
8
  const { hiddenUI, subvariantOptions } = useWidgetConfig();
9
9
  const swapOnly = useSwapOnly();
10
10
  const { pathname } = useLocation();
11
- const expansionType = pathname === navigationRoutes.home ? ExpansionType.Routes : pathname.endsWith(navigationRoutes.fromToken) ? ExpansionType.FromChain : pathname.endsWith(navigationRoutes.toToken) ? ExpansionType.ToChain : null;
12
- return [(expansionType === ExpansionType.FromChain || expansionType === ExpansionType.ToChain) && !(swapOnly && expansionType === ExpansionType.ToChain) && !hiddenUI?.includes(HiddenUI.ChainSelect) && !subvariantOptions?.wide?.disableChainSidebar, expansionType];
11
+ const expansionType = pathname === navigationRoutes.home ? "routes" : pathname.endsWith(navigationRoutes.fromToken) ? "fromChain" : pathname.endsWith(navigationRoutes.toToken) ? "toChain" : null;
12
+ return [(expansionType === "fromChain" || expansionType === "toChain") && !(swapOnly && expansionType === "toChain") && !hiddenUI?.includes("chainSelect") && !subvariantOptions?.wide?.disableChainSidebar, expansionType];
13
13
  };
14
14
  //#endregion
15
15
  export { useHasChainExpansion };
@@ -1 +1 @@
1
- {"version":3,"file":"useHasChainExpansion.js","names":[],"sources":["../../../src/hooks/useHasChainExpansion.ts"],"sourcesContent":["import { useLocation } from '@tanstack/react-router'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { ExpansionType, HiddenUI } from '../types/widget.js'\nimport { navigationRoutes } from '../utils/navigationRoutes.js'\nimport { useSwapOnly } from './useSwapOnly.js'\n\nexport const useHasChainExpansion = (): readonly [\n boolean,\n ExpansionType | null,\n] => {\n const { hiddenUI, subvariantOptions } = useWidgetConfig()\n const swapOnly = useSwapOnly()\n const { pathname } = useLocation()\n\n const expansionType =\n pathname === navigationRoutes.home\n ? ExpansionType.Routes\n : pathname.endsWith(navigationRoutes.fromToken)\n ? ExpansionType.FromChain\n : pathname.endsWith(navigationRoutes.toToken)\n ? ExpansionType.ToChain\n : null\n\n const withChainExpansion =\n (expansionType === ExpansionType.FromChain ||\n expansionType === ExpansionType.ToChain) &&\n !(swapOnly && expansionType === ExpansionType.ToChain) &&\n !hiddenUI?.includes(HiddenUI.ChainSelect) &&\n !subvariantOptions?.wide?.disableChainSidebar\n\n return [withChainExpansion, expansionType] as const\n}\n"],"mappings":";;;;;;AAMA,MAAa,6BAGR;CACH,MAAM,EAAE,UAAU,sBAAsB,iBAAiB;CACzD,MAAM,WAAW,aAAa;CAC9B,MAAM,EAAE,aAAa,aAAa;CAElC,MAAM,gBACJ,aAAa,iBAAiB,OAC1B,cAAc,SACd,SAAS,SAAS,iBAAiB,UAAU,GAC3C,cAAc,YACd,SAAS,SAAS,iBAAiB,QAAQ,GACzC,cAAc,UACd;AASV,QAAO,EANJ,kBAAkB,cAAc,aAC/B,kBAAkB,cAAc,YAClC,EAAE,YAAY,kBAAkB,cAAc,YAC9C,CAAC,UAAU,SAAS,SAAS,YAAY,IACzC,CAAC,mBAAmB,MAAM,qBAEA,cAAc"}
1
+ {"version":3,"file":"useHasChainExpansion.js","names":[],"sources":["../../../src/hooks/useHasChainExpansion.ts"],"sourcesContent":["import { useLocation } from '@tanstack/react-router'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { ExpansionType, HiddenUI } from '../types/widget.js'\nimport { navigationRoutes } from '../utils/navigationRoutes.js'\nimport { useSwapOnly } from './useSwapOnly.js'\n\nexport const useHasChainExpansion = (): readonly [\n boolean,\n ExpansionType | null,\n] => {\n const { hiddenUI, subvariantOptions } = useWidgetConfig()\n const swapOnly = useSwapOnly()\n const { pathname } = useLocation()\n\n const expansionType =\n pathname === navigationRoutes.home\n ? ExpansionType.Routes\n : pathname.endsWith(navigationRoutes.fromToken)\n ? ExpansionType.FromChain\n : pathname.endsWith(navigationRoutes.toToken)\n ? ExpansionType.ToChain\n : null\n\n const withChainExpansion =\n (expansionType === ExpansionType.FromChain ||\n expansionType === ExpansionType.ToChain) &&\n !(swapOnly && expansionType === ExpansionType.ToChain) &&\n !hiddenUI?.includes(HiddenUI.ChainSelect) &&\n !subvariantOptions?.wide?.disableChainSidebar\n\n return [withChainExpansion, expansionType] as const\n}\n"],"mappings":";;;;;;AAMA,MAAa,6BAGR;CACH,MAAM,EAAE,UAAU,sBAAsB,iBAAiB;CACzD,MAAM,WAAW,aAAa;CAC9B,MAAM,EAAE,aAAa,aAAa;CAElC,MAAM,gBACJ,aAAa,iBAAiB,OAAA,WAE1B,SAAS,SAAS,iBAAiB,UAAU,GAAA,cAE3C,SAAS,SAAS,iBAAiB,QAAQ,GAAA,YAEzC;AASV,QAAO,EANJ,kBAAA,eACC,kBAAA,cACF,EAAE,YAAY,kBAAA,cACd,CAAC,UAAU,SAAA,cAA8B,IACzC,CAAC,mBAAmB,MAAM,qBAEA,cAAc"}
@@ -1,4 +1,4 @@
1
- import { ElementId, getAppContainer, getHeaderElement, getScrollableContainer } from "../utils/elements.js";
1
+ import { getAppContainer, getHeaderElement, getScrollableContainer } from "../utils/elements.js";
2
2
  import { useDefaultElementId } from "./useDefaultElementId.js";
3
3
  import { useLayoutEffect, useState } from "react";
4
4
  import { debounce, useTheme } from "@mui/material";
@@ -13,7 +13,7 @@ const getContentHeight = (elementId, listParentRef) => {
13
13
  listParentElement.style.height = "0";
14
14
  }
15
15
  if (!containerElement || !headerElement) {
16
- console.warn(`Can't find ${ElementId.ScrollableContainer} or ${ElementId.Header} id.`);
16
+ console.warn(`Can't find widget-scrollable-container or widget-header id.`);
17
17
  return 0;
18
18
  }
19
19
  const { height: containerHeight } = containerElement.getBoundingClientRect();
@@ -1 +1 @@
1
- {"version":3,"file":"useListHeight.js","names":[],"sources":["../../../src/hooks/useListHeight.ts"],"sourcesContent":["import { debounce, useTheme } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useLayoutEffect, useState } from 'react'\nimport {\n ElementId,\n getAppContainer,\n getHeaderElement,\n getScrollableContainer,\n} from '../utils/elements.js'\nimport { useDefaultElementId } from './useDefaultElementId.js'\n\nconst getContentHeight = (\n elementId: string,\n listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null>\n) => {\n const containerElement = getScrollableContainer(elementId)\n\n const headerElement = getHeaderElement(elementId)\n\n const listParentElement = listParentRef?.current\n\n let oldHeight: string | undefined\n\n // This covers the case where in full height flex mode when the browser height is reduced\n // - this allows a virtualised list to be made smaller\n if (listParentElement) {\n oldHeight = listParentElement.style.height\n listParentElement.style.height = '0'\n }\n\n if (!containerElement || !headerElement) {\n console.warn(\n `Can't find ${ElementId.ScrollableContainer} or ${ElementId.Header} id.`\n )\n return 0\n }\n const { height: containerHeight } = containerElement.getBoundingClientRect()\n const { height: headerHeight } = headerElement.getBoundingClientRect()\n\n // This covers the case where in full height flex mode when the browser height is reduced the\n // - this allows a virtualised list to be set to minimum size\n if (listParentElement && oldHeight) {\n listParentElement.style.height = oldHeight\n }\n\n return containerHeight - headerHeight\n}\n\ninterface UseContentHeightProps {\n listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null>\n headerRef?: RefObject<HTMLElement | null>\n}\n\nconst defaultMinListHeight = 360\nconst minMobileListHeight = 160\n\n// NOTE: this hook is implicitly tied to the widget height functionality in the\n// AppExpandedContainer, RelativeContainer and CssBaselineContainer components as defined in AppContainer.ts\n// CSS changes in those components can have implications for the functionality in this hook\n\nexport const useListHeight = ({\n listParentRef,\n headerRef,\n}: UseContentHeightProps): { listHeight: number } => {\n const elementId = useDefaultElementId() ?? ''\n const [contentHeight, setContentHeight] = useState<number>(0)\n const theme = useTheme()\n\n useLayoutEffect(() => {\n const handleResize = () => {\n setContentHeight(getContentHeight(elementId, listParentRef))\n }\n\n const processResize = debounce(() => handleResize(), 40)\n\n // calling this on initial mount prevents the lists resizing appearing glitchy\n handleResize()\n\n const appContainer = getAppContainer(elementId)\n\n let resizeObserver: ResizeObserver\n if (appContainer) {\n resizeObserver = new ResizeObserver(processResize)\n resizeObserver.observe(appContainer)\n }\n\n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n }\n }, [elementId, listParentRef])\n\n const minListHeight =\n theme.container?.height === '100%'\n ? minMobileListHeight\n : defaultMinListHeight\n\n const listHeight = Math.max(\n contentHeight - (headerRef?.current?.offsetHeight ?? 0),\n minListHeight\n )\n\n return {\n listHeight,\n }\n}\n"],"mappings":";;;;;AAWA,MAAM,oBACJ,WACA,kBACG;CACH,MAAM,mBAAmB,uBAAuB,UAAU;CAE1D,MAAM,gBAAgB,iBAAiB,UAAU;CAEjD,MAAM,oBAAoB,eAAe;CAEzC,IAAI;AAIJ,KAAI,mBAAmB;AACrB,cAAY,kBAAkB,MAAM;AACpC,oBAAkB,MAAM,SAAS;;AAGnC,KAAI,CAAC,oBAAoB,CAAC,eAAe;AACvC,UAAQ,KACN,cAAc,UAAU,oBAAoB,MAAM,UAAU,OAAO,MACpE;AACD,SAAO;;CAET,MAAM,EAAE,QAAQ,oBAAoB,iBAAiB,uBAAuB;CAC5E,MAAM,EAAE,QAAQ,iBAAiB,cAAc,uBAAuB;AAItE,KAAI,qBAAqB,UACvB,mBAAkB,MAAM,SAAS;AAGnC,QAAO,kBAAkB;;AAQ3B,MAAM,uBAAuB;AAC7B,MAAM,sBAAsB;AAM5B,MAAa,iBAAiB,EAC5B,eACA,gBACmD;CACnD,MAAM,YAAY,qBAAqB,IAAI;CAC3C,MAAM,CAAC,eAAe,oBAAoB,SAAiB,EAAE;CAC7D,MAAM,QAAQ,UAAU;AAExB,uBAAsB;EACpB,MAAM,qBAAqB;AACzB,oBAAiB,iBAAiB,WAAW,cAAc,CAAC;;EAG9D,MAAM,gBAAgB,eAAe,cAAc,EAAE,GAAG;AAGxD,gBAAc;EAEd,MAAM,eAAe,gBAAgB,UAAU;EAE/C,IAAI;AACJ,MAAI,cAAc;AAChB,oBAAiB,IAAI,eAAe,cAAc;AAClD,kBAAe,QAAQ,aAAa;;AAGtC,eAAa;AACX,OAAI,eACF,gBAAe,YAAY;;IAG9B,CAAC,WAAW,cAAc,CAAC;CAE9B,MAAM,gBACJ,MAAM,WAAW,WAAW,SACxB,sBACA;AAON,QAAO,EACL,YANiB,KAAK,IACtB,iBAAiB,WAAW,SAAS,gBAAgB,IACrD,cACD,EAIA"}
1
+ {"version":3,"file":"useListHeight.js","names":[],"sources":["../../../src/hooks/useListHeight.ts"],"sourcesContent":["import { debounce, useTheme } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useLayoutEffect, useState } from 'react'\nimport {\n ElementId,\n getAppContainer,\n getHeaderElement,\n getScrollableContainer,\n} from '../utils/elements.js'\nimport { useDefaultElementId } from './useDefaultElementId.js'\n\nconst getContentHeight = (\n elementId: string,\n listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null>\n) => {\n const containerElement = getScrollableContainer(elementId)\n\n const headerElement = getHeaderElement(elementId)\n\n const listParentElement = listParentRef?.current\n\n let oldHeight: string | undefined\n\n // This covers the case where in full height flex mode when the browser height is reduced\n // - this allows a virtualised list to be made smaller\n if (listParentElement) {\n oldHeight = listParentElement.style.height\n listParentElement.style.height = '0'\n }\n\n if (!containerElement || !headerElement) {\n console.warn(\n `Can't find ${ElementId.ScrollableContainer} or ${ElementId.Header} id.`\n )\n return 0\n }\n const { height: containerHeight } = containerElement.getBoundingClientRect()\n const { height: headerHeight } = headerElement.getBoundingClientRect()\n\n // This covers the case where in full height flex mode when the browser height is reduced the\n // - this allows a virtualised list to be set to minimum size\n if (listParentElement && oldHeight) {\n listParentElement.style.height = oldHeight\n }\n\n return containerHeight - headerHeight\n}\n\ninterface UseContentHeightProps {\n listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null>\n headerRef?: RefObject<HTMLElement | null>\n}\n\nconst defaultMinListHeight = 360\nconst minMobileListHeight = 160\n\n// NOTE: this hook is implicitly tied to the widget height functionality in the\n// AppExpandedContainer, RelativeContainer and CssBaselineContainer components as defined in AppContainer.ts\n// CSS changes in those components can have implications for the functionality in this hook\n\nexport const useListHeight = ({\n listParentRef,\n headerRef,\n}: UseContentHeightProps): { listHeight: number } => {\n const elementId = useDefaultElementId() ?? ''\n const [contentHeight, setContentHeight] = useState<number>(0)\n const theme = useTheme()\n\n useLayoutEffect(() => {\n const handleResize = () => {\n setContentHeight(getContentHeight(elementId, listParentRef))\n }\n\n const processResize = debounce(() => handleResize(), 40)\n\n // calling this on initial mount prevents the lists resizing appearing glitchy\n handleResize()\n\n const appContainer = getAppContainer(elementId)\n\n let resizeObserver: ResizeObserver\n if (appContainer) {\n resizeObserver = new ResizeObserver(processResize)\n resizeObserver.observe(appContainer)\n }\n\n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n }\n }, [elementId, listParentRef])\n\n const minListHeight =\n theme.container?.height === '100%'\n ? minMobileListHeight\n : defaultMinListHeight\n\n const listHeight = Math.max(\n contentHeight - (headerRef?.current?.offsetHeight ?? 0),\n minListHeight\n )\n\n return {\n listHeight,\n }\n}\n"],"mappings":";;;;;AAWA,MAAM,oBACJ,WACA,kBACG;CACH,MAAM,mBAAmB,uBAAuB,UAAU;CAE1D,MAAM,gBAAgB,iBAAiB,UAAU;CAEjD,MAAM,oBAAoB,eAAe;CAEzC,IAAI;AAIJ,KAAI,mBAAmB;AACrB,cAAY,kBAAkB,MAAM;AACpC,oBAAkB,MAAM,SAAS;;AAGnC,KAAI,CAAC,oBAAoB,CAAC,eAAe;AACvC,UAAQ,KACN,8DACD;AACD,SAAO;;CAET,MAAM,EAAE,QAAQ,oBAAoB,iBAAiB,uBAAuB;CAC5E,MAAM,EAAE,QAAQ,iBAAiB,cAAc,uBAAuB;AAItE,KAAI,qBAAqB,UACvB,mBAAkB,MAAM,SAAS;AAGnC,QAAO,kBAAkB;;AAQ3B,MAAM,uBAAuB;AAC7B,MAAM,sBAAsB;AAM5B,MAAa,iBAAiB,EAC5B,eACA,gBACmD;CACnD,MAAM,YAAY,qBAAqB,IAAI;CAC3C,MAAM,CAAC,eAAe,oBAAoB,SAAiB,EAAE;CAC7D,MAAM,QAAQ,UAAU;AAExB,uBAAsB;EACpB,MAAM,qBAAqB;AACzB,oBAAiB,iBAAiB,WAAW,cAAc,CAAC;;EAG9D,MAAM,gBAAgB,eAAe,cAAc,EAAE,GAAG;AAGxD,gBAAc;EAEd,MAAM,eAAe,gBAAgB,UAAU;EAE/C,IAAI;AACJ,MAAI,cAAc;AAChB,oBAAiB,IAAI,eAAe,cAAc;AAClD,kBAAe,QAAQ,aAAa;;AAGtC,eAAa;AACX,OAAI,eACF,gBAAe,YAAY;;IAG9B,CAAC,WAAW,cAAc,CAAC;CAE9B,MAAM,gBACJ,MAAM,WAAW,WAAW,SACxB,sBACA;AAON,QAAO,EACL,YANiB,KAAK,IACtB,iBAAiB,WAAW,SAAS,gBAAgB,IACrD,cACD,EAIA"}
@@ -1,5 +1,5 @@
1
1
  import { useWidgetEvents } from "./useWidgetEvents.js";
2
- import { WidgetEvent } from "../types/events.js";
2
+ import "../types/events.js";
3
3
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
4
4
  import { useSDKClient } from "../providers/SDKClientProvider.js";
5
5
  import { getQueryKey } from "../utils/queries.js";
@@ -26,14 +26,14 @@ const useRouteExecution = ({ routeId, executeInBackground, onAcceptExchangeRateU
26
26
  const clonedUpdatedRoute = structuredClone(updatedRoute);
27
27
  updateRoute(clonedUpdatedRoute);
28
28
  const action = getUpdatedAction(routeExecution.route, clonedUpdatedRoute);
29
- if (action) emitter.emit(WidgetEvent.RouteExecutionUpdated, {
29
+ if (action) emitter.emit("routeExecutionUpdated", {
30
30
  route: clonedUpdatedRoute,
31
31
  action
32
32
  });
33
33
  const executionCompleted = isRouteDone(clonedUpdatedRoute);
34
34
  const executionFailed = isRouteFailed(clonedUpdatedRoute);
35
- if (executionCompleted) emitter.emit(WidgetEvent.RouteExecutionCompleted, clonedUpdatedRoute);
36
- if (executionFailed && action) emitter.emit(WidgetEvent.RouteExecutionFailed, {
35
+ if (executionCompleted) emitter.emit("routeExecutionCompleted", clonedUpdatedRoute);
36
+ if (executionFailed && action) emitter.emit("routeExecutionFailed", {
37
37
  route: clonedUpdatedRoute,
38
38
  action
39
39
  });
@@ -81,7 +81,7 @@ const useRouteExecution = ({ routeId, executeInBackground, onAcceptExchangeRateU
81
81
  },
82
82
  onMutate: () => {
83
83
  console.log("Execution started.", routeId);
84
- if (routeExecution) emitter.emit(WidgetEvent.RouteExecutionStarted, routeExecution.route);
84
+ if (routeExecution) emitter.emit("routeExecutionStarted", routeExecution.route);
85
85
  }
86
86
  });
87
87
  const resumeRouteMutation = useMutation({
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteExecution.js","names":[],"sources":["../../../src/hooks/useRouteExecution.ts"],"sourcesContent":["import type { ExchangeRateUpdateParams, Route, RouteExtended } from '@lifi/sdk'\nimport { executeRoute, resumeRoute, updateRouteExecution } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport {\n useRouteExecutionStore,\n useRouteExecutionStoreContext,\n} from '../stores/routes/RouteExecutionStore.js'\nimport type { RouteExecutionStatus } from '../stores/routes/types.js'\nimport {\n getUpdatedAction,\n isRouteActive,\n isRouteDone,\n isRouteFailed,\n} from '../stores/routes/utils.js'\nimport { WidgetEvent } from '../types/events.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\ninterface RouteExecutionProps {\n routeId: string\n executeInBackground?: boolean\n onAcceptExchangeRateUpdate?(\n resolver: (value: boolean) => void,\n data: ExchangeRateUpdateParams\n ): void\n}\n\nexport const useRouteExecution = ({\n routeId,\n executeInBackground,\n onAcceptExchangeRateUpdate,\n}: RouteExecutionProps): {\n executeRoute: () => void\n restartRoute: () => void\n deleteRoute: () => void\n route: RouteExtended | undefined\n status: RouteExecutionStatus | undefined\n} => {\n const queryClient = useQueryClient()\n const { account } = useAccount()\n const resumedAfterMount = useRef(false)\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const emitter = useWidgetEvents()\n const routeExecutionStoreContext = useRouteExecutionStoreContext()\n const routeExecution = useRouteExecutionStore(\n (state) => state.routes[routeId]\n )\n const [updateRoute, deleteRoute] = useRouteExecutionStore((state) => [\n state.updateRoute,\n state.deleteRoute,\n ])\n\n const updateRouteHook = (updatedRoute: Route) => {\n const routeExecution =\n routeExecutionStoreContext.getState().routes[updatedRoute.id]\n if (!routeExecution) {\n return\n }\n const clonedUpdatedRoute = structuredClone(updatedRoute)\n updateRoute(clonedUpdatedRoute)\n const action = getUpdatedAction(routeExecution.route, clonedUpdatedRoute)\n if (action) {\n emitter.emit(WidgetEvent.RouteExecutionUpdated, {\n route: clonedUpdatedRoute,\n action,\n })\n }\n const executionCompleted = isRouteDone(clonedUpdatedRoute)\n const executionFailed = isRouteFailed(clonedUpdatedRoute)\n if (executionCompleted) {\n emitter.emit(WidgetEvent.RouteExecutionCompleted, clonedUpdatedRoute)\n }\n if (executionFailed && action) {\n emitter.emit(WidgetEvent.RouteExecutionFailed, {\n route: clonedUpdatedRoute,\n action,\n })\n }\n if (executionCompleted || executionFailed) {\n const invalidateKeys = [\n [\n getQueryKey('token-balances', keyPrefix),\n clonedUpdatedRoute.fromAddress,\n clonedUpdatedRoute.fromChainId,\n ],\n [\n getQueryKey('token-balances', keyPrefix),\n clonedUpdatedRoute.toAddress,\n clonedUpdatedRoute.toChainId,\n ],\n [getQueryKey('transaction-history', keyPrefix)],\n ]\n for (const key of invalidateKeys) {\n queryClient.invalidateQueries(\n {\n queryKey: key,\n exact: false,\n refetchType: 'all',\n },\n { cancelRefetch: false }\n )\n }\n }\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Route updated.', clonedUpdatedRoute)\n }\n\n const acceptExchangeRateUpdateHook = async (\n params: ExchangeRateUpdateParams\n ) => {\n if (!onAcceptExchangeRateUpdate) {\n return false\n }\n\n const accepted = await new Promise<boolean>((resolve) =>\n onAcceptExchangeRateUpdate(resolve, params)\n )\n\n return accepted\n }\n\n const executeRouteMutation = useMutation({\n mutationFn: () => {\n if (!account.isConnected) {\n throw new Error('Account is not connected.')\n }\n if (!routeExecution?.route) {\n throw new Error('Execution route not found.')\n }\n queryClient.removeQueries({\n queryKey: [getQueryKey('routes', keyPrefix)],\n exact: false,\n })\n return executeRoute(sdkClient, routeExecution.route, {\n updateRouteHook,\n acceptExchangeRateUpdateHook,\n infiniteApproval: false,\n executeInBackground,\n ...sdkClient.config?.executionOptions,\n })\n },\n onMutate: () => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Execution started.', routeId)\n if (routeExecution) {\n emitter.emit(WidgetEvent.RouteExecutionStarted, routeExecution.route)\n }\n },\n })\n\n const resumeRouteMutation = useMutation({\n mutationFn: (resumedRoute?: Route) => {\n if (!account.isConnected) {\n throw new Error('Account is not connected.')\n }\n if (!routeExecution?.route) {\n throw new Error('Execution route not found.')\n }\n return resumeRoute(sdkClient, resumedRoute ?? routeExecution.route, {\n updateRouteHook,\n acceptExchangeRateUpdateHook,\n infiniteApproval: false,\n executeInBackground,\n })\n },\n onMutate: () => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Resumed to execution.', routeId)\n },\n })\n\n const _executeRoute = useCallback(() => {\n executeRouteMutation.mutateAsync(undefined, {\n onError: (error) => {\n console.warn('Execution failed!', routeId, error)\n },\n onSuccess: (route: Route) => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Executed successfully!', route)\n },\n })\n }, [executeRouteMutation, routeId])\n\n const _resumeRoute = useCallback(\n (route?: Route) => {\n resumeRouteMutation.mutateAsync(route, {\n onError: (error) => {\n console.warn('Resumed execution failed.', routeId, error)\n },\n onSuccess: (route) => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Resumed execution successful.', route)\n },\n })\n },\n [resumeRouteMutation, routeId]\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n const restartRouteMutation = useCallback(() => {\n _resumeRoute(routeExecution?.route)\n }, [_resumeRoute, routeExecution?.route, routeId])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n const deleteRouteMutation = useCallback(() => {\n deleteRoute(routeId)\n }, [routeId])\n\n // Resume route execution after page reload\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n useEffect(() => {\n // Check if route is eligible for automatic resuming\n const route = routeExecutionStoreContext.getState().routes[routeId]?.route\n if (\n isRouteActive(route) &&\n account.isConnected &&\n !resumedAfterMount.current\n ) {\n resumedAfterMount.current = true\n _resumeRoute()\n }\n\n // Move execution to background on unmount\n return () => {\n const route = routeExecutionStoreContext.getState().routes[routeId]?.route\n if (!route || !isRouteActive(route)) {\n return\n }\n updateRouteExecution(route, { executeInBackground: true })\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Move route execution to background.', routeId)\n resumedAfterMount.current = false\n }\n }, [account.isConnected, routeExecutionStoreContext, routeId])\n\n return {\n executeRoute: _executeRoute,\n restartRoute: restartRouteMutation,\n deleteRoute: deleteRouteMutation,\n route: routeExecution?.route,\n status: routeExecution?.status,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useRouteExecution.js","names":[],"sources":["../../../src/hooks/useRouteExecution.ts"],"sourcesContent":["import type { ExchangeRateUpdateParams, Route, RouteExtended } from '@lifi/sdk'\nimport { executeRoute, resumeRoute, updateRouteExecution } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport {\n useRouteExecutionStore,\n useRouteExecutionStoreContext,\n} from '../stores/routes/RouteExecutionStore.js'\nimport type { RouteExecutionStatus } from '../stores/routes/types.js'\nimport {\n getUpdatedAction,\n isRouteActive,\n isRouteDone,\n isRouteFailed,\n} from '../stores/routes/utils.js'\nimport { WidgetEvent } from '../types/events.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\ninterface RouteExecutionProps {\n routeId: string\n executeInBackground?: boolean\n onAcceptExchangeRateUpdate?(\n resolver: (value: boolean) => void,\n data: ExchangeRateUpdateParams\n ): void\n}\n\nexport const useRouteExecution = ({\n routeId,\n executeInBackground,\n onAcceptExchangeRateUpdate,\n}: RouteExecutionProps): {\n executeRoute: () => void\n restartRoute: () => void\n deleteRoute: () => void\n route: RouteExtended | undefined\n status: RouteExecutionStatus | undefined\n} => {\n const queryClient = useQueryClient()\n const { account } = useAccount()\n const resumedAfterMount = useRef(false)\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const emitter = useWidgetEvents()\n const routeExecutionStoreContext = useRouteExecutionStoreContext()\n const routeExecution = useRouteExecutionStore(\n (state) => state.routes[routeId]\n )\n const [updateRoute, deleteRoute] = useRouteExecutionStore((state) => [\n state.updateRoute,\n state.deleteRoute,\n ])\n\n const updateRouteHook = (updatedRoute: Route) => {\n const routeExecution =\n routeExecutionStoreContext.getState().routes[updatedRoute.id]\n if (!routeExecution) {\n return\n }\n const clonedUpdatedRoute = structuredClone(updatedRoute)\n updateRoute(clonedUpdatedRoute)\n const action = getUpdatedAction(routeExecution.route, clonedUpdatedRoute)\n if (action) {\n emitter.emit(WidgetEvent.RouteExecutionUpdated, {\n route: clonedUpdatedRoute,\n action,\n })\n }\n const executionCompleted = isRouteDone(clonedUpdatedRoute)\n const executionFailed = isRouteFailed(clonedUpdatedRoute)\n if (executionCompleted) {\n emitter.emit(WidgetEvent.RouteExecutionCompleted, clonedUpdatedRoute)\n }\n if (executionFailed && action) {\n emitter.emit(WidgetEvent.RouteExecutionFailed, {\n route: clonedUpdatedRoute,\n action,\n })\n }\n if (executionCompleted || executionFailed) {\n const invalidateKeys = [\n [\n getQueryKey('token-balances', keyPrefix),\n clonedUpdatedRoute.fromAddress,\n clonedUpdatedRoute.fromChainId,\n ],\n [\n getQueryKey('token-balances', keyPrefix),\n clonedUpdatedRoute.toAddress,\n clonedUpdatedRoute.toChainId,\n ],\n [getQueryKey('transaction-history', keyPrefix)],\n ]\n for (const key of invalidateKeys) {\n queryClient.invalidateQueries(\n {\n queryKey: key,\n exact: false,\n refetchType: 'all',\n },\n { cancelRefetch: false }\n )\n }\n }\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Route updated.', clonedUpdatedRoute)\n }\n\n const acceptExchangeRateUpdateHook = async (\n params: ExchangeRateUpdateParams\n ) => {\n if (!onAcceptExchangeRateUpdate) {\n return false\n }\n\n const accepted = await new Promise<boolean>((resolve) =>\n onAcceptExchangeRateUpdate(resolve, params)\n )\n\n return accepted\n }\n\n const executeRouteMutation = useMutation({\n mutationFn: () => {\n if (!account.isConnected) {\n throw new Error('Account is not connected.')\n }\n if (!routeExecution?.route) {\n throw new Error('Execution route not found.')\n }\n queryClient.removeQueries({\n queryKey: [getQueryKey('routes', keyPrefix)],\n exact: false,\n })\n return executeRoute(sdkClient, routeExecution.route, {\n updateRouteHook,\n acceptExchangeRateUpdateHook,\n infiniteApproval: false,\n executeInBackground,\n ...sdkClient.config?.executionOptions,\n })\n },\n onMutate: () => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Execution started.', routeId)\n if (routeExecution) {\n emitter.emit(WidgetEvent.RouteExecutionStarted, routeExecution.route)\n }\n },\n })\n\n const resumeRouteMutation = useMutation({\n mutationFn: (resumedRoute?: Route) => {\n if (!account.isConnected) {\n throw new Error('Account is not connected.')\n }\n if (!routeExecution?.route) {\n throw new Error('Execution route not found.')\n }\n return resumeRoute(sdkClient, resumedRoute ?? routeExecution.route, {\n updateRouteHook,\n acceptExchangeRateUpdateHook,\n infiniteApproval: false,\n executeInBackground,\n })\n },\n onMutate: () => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Resumed to execution.', routeId)\n },\n })\n\n const _executeRoute = useCallback(() => {\n executeRouteMutation.mutateAsync(undefined, {\n onError: (error) => {\n console.warn('Execution failed!', routeId, error)\n },\n onSuccess: (route: Route) => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Executed successfully!', route)\n },\n })\n }, [executeRouteMutation, routeId])\n\n const _resumeRoute = useCallback(\n (route?: Route) => {\n resumeRouteMutation.mutateAsync(route, {\n onError: (error) => {\n console.warn('Resumed execution failed.', routeId, error)\n },\n onSuccess: (route) => {\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Resumed execution successful.', route)\n },\n })\n },\n [resumeRouteMutation, routeId]\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n const restartRouteMutation = useCallback(() => {\n _resumeRoute(routeExecution?.route)\n }, [_resumeRoute, routeExecution?.route, routeId])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n const deleteRouteMutation = useCallback(() => {\n deleteRoute(routeId)\n }, [routeId])\n\n // Resume route execution after page reload\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when routeId changes\n useEffect(() => {\n // Check if route is eligible for automatic resuming\n const route = routeExecutionStoreContext.getState().routes[routeId]?.route\n if (\n isRouteActive(route) &&\n account.isConnected &&\n !resumedAfterMount.current\n ) {\n resumedAfterMount.current = true\n _resumeRoute()\n }\n\n // Move execution to background on unmount\n return () => {\n const route = routeExecutionStoreContext.getState().routes[routeId]?.route\n if (!route || !isRouteActive(route)) {\n return\n }\n updateRouteExecution(route, { executeInBackground: true })\n // biome-ignore lint/suspicious/noConsole: logs route information\n console.log('Move route execution to background.', routeId)\n resumedAfterMount.current = false\n }\n }, [account.isConnected, routeExecutionStoreContext, routeId])\n\n return {\n executeRoute: _executeRoute,\n restartRoute: restartRouteMutation,\n deleteRoute: deleteRouteMutation,\n route: routeExecution?.route,\n status: routeExecution?.status,\n }\n}\n"],"mappings":"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"}