@lifi/widget 4.0.0-beta.14 → 4.0.0-beta.18
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.
- package/dist/esm/AppDefault.js +31 -29
- package/dist/esm/AppDefault.js.map +1 -1
- package/dist/esm/AppLayout.js +2 -2
- package/dist/esm/AppLayout.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInput.js +2 -2
- package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputStartAdornment.js.map +1 -1
- package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
- package/dist/esm/components/AppContainer.js +3 -3
- package/dist/esm/components/AppContainer.js.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
- package/dist/esm/components/ChainSelect/useChainSelect.js.map +1 -1
- package/dist/esm/components/Chains/AllChainsAvatar.js +7 -1
- package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
- package/dist/esm/components/Chains/SelectChainContent.js.map +1 -1
- package/dist/esm/components/ContractComponent/ItemPrice.js +1 -1
- package/dist/esm/components/ContractComponent/ItemPrice.js.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFTBase.js +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFTBase.js.map +1 -1
- package/dist/esm/components/Dialog/Dialog.js.map +1 -1
- package/dist/esm/components/Expansion/Expansion.js +4 -4
- package/dist/esm/components/Expansion/Expansion.js.map +1 -1
- package/dist/esm/components/Header/ActivitiesButton.js +1 -1
- package/dist/esm/components/Header/ActivitiesButton.js.map +1 -1
- package/dist/esm/components/Header/Header.js +2 -2
- package/dist/esm/components/Header/Header.js.map +1 -1
- package/dist/esm/components/Header/NavigationHeader.js +3 -3
- package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
- package/dist/esm/components/Header/WalletHeader.js +3 -3
- package/dist/esm/components/Header/WalletHeader.js.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
- package/dist/esm/components/IconTypography.js.map +1 -1
- package/dist/esm/components/Messages/AlertMessage.js +1 -1
- package/dist/esm/components/Messages/AlertMessage.js.map +1 -1
- package/dist/esm/components/PageEntered.js +2 -2
- package/dist/esm/components/PageEntered.js.map +1 -1
- package/dist/esm/components/ReverseTokensButton/ReverseTokensButton.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCard.js +2 -2
- package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCardEssentials.js +10 -4
- package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteToken.js +2 -2
- package/dist/esm/components/RouteCard/RouteToken.js.map +1 -1
- package/dist/esm/components/Routes/RoutesExpanded.js +3 -3
- package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
- package/dist/esm/components/SelectChainAndToken.js +8 -5
- package/dist/esm/components/SelectChainAndToken.js.map +1 -1
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js +1 -2
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletButton.js +4 -4
- package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +3 -3
- package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
- package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
- package/dist/esm/components/Step/Step.js +20 -9
- package/dist/esm/components/Step/Step.js.map +1 -1
- package/dist/esm/components/Step/StepActions.js +2 -2
- package/dist/esm/components/Step/StepActions.js.map +1 -1
- package/dist/esm/components/StepActions/StepActions.js +2 -2
- package/dist/esm/components/StepActions/StepActions.js.map +1 -1
- package/dist/esm/components/Tabs/Tabs.style.js.map +1 -1
- package/dist/esm/components/Timer/StepTimer.js.map +1 -1
- package/dist/esm/components/Timer/TimerContent.js +1 -0
- package/dist/esm/components/Timer/TimerContent.js.map +1 -1
- package/dist/esm/components/Token/Token.js +2 -2
- package/dist/esm/components/Token/Token.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +6 -4
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
- package/dist/esm/components/TokenList/TokenList.js +2 -2
- package/dist/esm/components/TokenList/TokenList.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.js +2 -2
- package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
- package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +2 -3
- package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
- package/dist/esm/components/TransactionDetails.js +5 -2
- package/dist/esm/components/TransactionDetails.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/timer/time.js.map +1 -1
- package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
- package/dist/esm/hooks/useActionMessage.js +2 -2
- package/dist/esm/hooks/useActionMessage.js.map +1 -1
- package/dist/esm/hooks/useAddressActivity.js.map +1 -1
- package/dist/esm/hooks/useAddressValidation.js +3 -8
- package/dist/esm/hooks/useAddressValidation.js.map +1 -1
- package/dist/esm/hooks/useAvailableChains.js +2 -1
- package/dist/esm/hooks/useAvailableChains.js.map +1 -1
- package/dist/esm/hooks/useChain.js.map +1 -1
- package/dist/esm/hooks/useChains.js.map +1 -1
- package/dist/esm/hooks/useContactSupport.js +3 -3
- package/dist/esm/hooks/useContactSupport.js.map +1 -1
- package/dist/esm/hooks/useDebouncedWatch.js.map +1 -1
- package/dist/esm/hooks/useExplorer.js +15 -4
- package/dist/esm/hooks/useExplorer.js.map +1 -1
- package/dist/esm/hooks/useFilteredByTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useFromAmountThreshold.js.map +1 -1
- package/dist/esm/hooks/useFromTokenSufficiency.js.map +1 -1
- package/dist/esm/hooks/useGasRecommendation.js +2 -2
- package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
- package/dist/esm/hooks/useGasRefuel.js +2 -2
- package/dist/esm/hooks/useGasRefuel.js.map +1 -1
- package/dist/esm/hooks/useGasSufficiency.js +2 -2
- package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
- package/dist/esm/hooks/useHasChainExpansion.js +3 -3
- package/dist/esm/hooks/useHasChainExpansion.js.map +1 -1
- package/dist/esm/hooks/useIsContractAddress.js.map +1 -1
- package/dist/esm/hooks/useListHeight.js +2 -2
- package/dist/esm/hooks/useListHeight.js.map +1 -1
- package/dist/esm/hooks/useLongPress.js.map +1 -1
- package/dist/esm/hooks/useNavigateBack.js.map +1 -1
- package/dist/esm/hooks/useRouteExecution.js +5 -7
- package/dist/esm/hooks/useRouteExecution.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js +4 -4
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useScrollableContainer.js.map +1 -1
- package/dist/esm/hooks/useSwapOnly.js.map +1 -1
- package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +2 -2
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useToAddressReset.js +2 -2
- package/dist/esm/hooks/useToAddressReset.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokenBalances.js +2 -2
- package/dist/esm/hooks/useTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +4 -2
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useTransactionDetails.js.map +1 -1
- package/dist/esm/hooks/useTransactionHistory.js.map +1 -1
- package/dist/esm/hooks/useTransactionList.js +2 -3
- package/dist/esm/hooks/useTransactionList.js.map +1 -1
- package/dist/esm/hooks/useWidgetEvents.js.map +1 -1
- package/dist/esm/i18n/bn.json +3 -0
- package/dist/esm/i18n/de.json +3 -0
- package/dist/esm/i18n/en.json +3 -0
- package/dist/esm/i18n/es.json +3 -0
- package/dist/esm/i18n/fr.json +3 -0
- package/dist/esm/i18n/hi.json +3 -0
- package/dist/esm/i18n/id.json +3 -0
- package/dist/esm/i18n/it.json +3 -0
- package/dist/esm/i18n/ja.json +3 -0
- package/dist/esm/i18n/ko.json +3 -0
- package/dist/esm/i18n/pl.json +3 -0
- package/dist/esm/i18n/pt.json +3 -0
- package/dist/esm/i18n/th.json +3 -0
- package/dist/esm/i18n/tr.json +3 -0
- package/dist/esm/i18n/uk.json +3 -0
- package/dist/esm/i18n/vi.json +3 -0
- package/dist/esm/i18n/zh.json +3 -0
- package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js +1 -2
- package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js +1 -1
- package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js.map +1 -1
- package/dist/esm/pages/MainPage/MainPage.js +6 -6
- package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
- package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/RoutesPage/RoutesPage.js +3 -3
- package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
- package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
- package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
- package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +3 -3
- package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/BookmarksPage.js +1 -1
- package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +1 -1
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js +6 -6
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/LanguageSetting.js +2 -2
- package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SettingsPage.js +2 -2
- package/dist/esm/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/ThemeSettings.js +2 -2
- package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/StepActionRow.js +2 -2
- package/dist/esm/pages/TransactionDetailsPage/StepActionRow.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/StepActionsList.js +11 -5
- package/dist/esm/pages/TransactionDetailsPage/StepActionsList.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js +2 -2
- package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -1
- package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js +2 -2
- package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js +1 -1
- package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js +20 -21
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js +5 -6
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +14 -4
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionPage.js +15 -19
- package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
- package/dist/esm/providers/I18nProvider/i18n.js.map +1 -1
- package/dist/esm/providers/QueryClientProvider.js.map +1 -1
- package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
- package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
- package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/bookmarks/useBookmarkActions.js.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +2 -2
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/createChainOrderStore.js +2 -2
- package/dist/esm/stores/chains/createChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/useChainOrder.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/createFormStore.js.map +1 -1
- package/dist/esm/stores/form/useFieldActions.js +3 -3
- package/dist/esm/stores/form/useFieldActions.js.map +1 -1
- package/dist/esm/stores/form/useFieldValues.js.map +1 -1
- package/dist/esm/stores/form/useFormRef.js +2 -2
- package/dist/esm/stores/form/useFormRef.js.map +1 -1
- package/dist/esm/stores/form/useTouchedFields.js.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.js.map +1 -1
- package/dist/esm/stores/routes/RouteExecutionStore.js.map +1 -1
- package/dist/esm/stores/routes/createRouteExecutionStore.js +8 -9
- package/dist/esm/stores/routes/createRouteExecutionStore.js.map +1 -1
- package/dist/esm/stores/routes/useRouteExecutionIndicator.js +2 -3
- package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
- package/dist/esm/stores/routes/utils.js.map +1 -1
- package/dist/esm/stores/settings/SettingsStore.js.map +1 -1
- package/dist/esm/stores/settings/createSettingsStore.js +1 -5
- package/dist/esm/stores/settings/createSettingsStore.js.map +1 -1
- package/dist/esm/stores/settings/useSettingsActions.js +2 -2
- package/dist/esm/stores/settings/useSettingsActions.js.map +1 -1
- package/dist/esm/stores/settings/useSplitSubvariantStore.js.map +1 -1
- package/dist/esm/themes/createTheme.js +4 -4
- package/dist/esm/themes/createTheme.js.map +1 -1
- package/dist/esm/types/events.d.ts +0 -5
- package/dist/esm/types/events.d.ts.map +1 -1
- package/dist/esm/types/events.js +0 -4
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/types/widget.d.ts +1 -5
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/converters.js.map +1 -1
- package/dist/esm/utils/elements.js +5 -12
- package/dist/esm/utils/elements.js.map +1 -1
- package/dist/esm/utils/format.js.map +1 -1
- package/dist/esm/utils/timer.js.map +1 -1
- package/dist/esm/utils/token.js.map +1 -1
- package/package.json +11 -11
- package/src/AppDefault.tsx +9 -11
- package/src/components/Chains/AllChainsAvatar.tsx +7 -1
- package/src/components/ContractComponent/ItemPrice.tsx +1 -1
- package/src/components/ContractComponent/NFT/NFTBase.tsx +1 -1
- package/src/components/Header/ActivitiesButton.tsx +1 -1
- package/src/components/IconTypography.ts +8 -8
- package/src/components/Messages/AlertMessage.tsx +1 -1
- package/src/components/RouteCard/RouteCardEssentials.tsx +2 -2
- package/src/components/SelectChainAndToken.tsx +1 -1
- package/src/components/SendToWallet/SendToWalletButton.tsx +1 -1
- package/src/components/Step/Step.tsx +6 -7
- package/src/components/Timer/TimerContent.tsx +1 -0
- package/src/components/Token/Token.tsx +2 -2
- package/src/components/TokenList/TokenDetailsSheetContent.tsx +6 -4
- package/src/components/TransactionCard/ActiveTransactionCard.tsx +1 -1
- package/src/components/TransactionDetails.tsx +1 -1
- package/src/config/version.ts +1 -1
- package/src/hooks/useActionMessage.ts +4 -3
- package/src/hooks/useAvailableChains.ts +1 -0
- package/src/hooks/useExplorer.ts +16 -5
- package/src/hooks/useRouteExecution.ts +0 -2
- package/src/hooks/useTokens.ts +2 -0
- package/src/pages/ActivitiesPage/ActivitiesPageMenuButton.tsx +1 -1
- package/src/pages/MainPage/MainPage.tsx +3 -3
- package/src/pages/RoutesPage/RoutesPage.tsx +6 -1
- package/src/pages/SendToWallet/BookmarksPage.tsx +1 -1
- package/src/pages/SendToWallet/RecentWalletsPage.tsx +1 -1
- package/src/pages/TransactionDetailsPage/StepActionRow.tsx +3 -2
- package/src/pages/TransactionDetailsPage/StepActionsList.tsx +19 -12
- package/src/pages/TransactionPage/ExchangeRateBottomSheet.tsx +1 -1
- package/src/pages/TransactionPage/StatusBottomSheet.tsx +1 -1
- package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +27 -5
- package/src/pages/TransactionPage/TransactionPage.tsx +2 -9
- package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
- package/src/stores/settings/createSettingsStore.ts +1 -9
- package/src/themes/createTheme.ts +4 -6
- package/src/types/events.ts +0 -5
- package/src/types/widget.ts +1 -4
- package/dist/esm/stores/routes/types.js +0 -14
- package/dist/esm/stores/routes/types.js.map +0 -1
|
@@ -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 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 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,5 +1,5 @@
|
|
|
1
1
|
import { useWidgetEvents } from "./useWidgetEvents.js";
|
|
2
|
-
import
|
|
2
|
+
import "../types/events.js";
|
|
3
3
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
4
4
|
import { useSwapOnly } from "./useSwapOnly.js";
|
|
5
5
|
import { useFieldValues } from "../stores/form/useFieldValues.js";
|
|
@@ -247,15 +247,15 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
247
247
|
const initialRoutes = routesResult?.routes ?? [];
|
|
248
248
|
if (shouldUseRelayerQuote && initialRoutes.length) {
|
|
249
249
|
setIntermediateRoutes(queryKey, initialRoutes);
|
|
250
|
-
emitter.emit(
|
|
250
|
+
emitter.emit("availableRoutes", initialRoutes);
|
|
251
251
|
} else if (shouldUseMainRoutes) {
|
|
252
|
-
emitter.emit(
|
|
252
|
+
emitter.emit("availableRoutes", initialRoutes);
|
|
253
253
|
return initialRoutes;
|
|
254
254
|
}
|
|
255
255
|
const relayerRouteResult = await relayerQuotePromise;
|
|
256
256
|
if (relayerRouteResult) {
|
|
257
257
|
initialRoutes.splice(1, 0, relayerRouteResult);
|
|
258
|
-
emitter.emit(
|
|
258
|
+
emitter.emit("availableRoutes", initialRoutes);
|
|
259
259
|
}
|
|
260
260
|
return initialRoutes;
|
|
261
261
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRoutes.js","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"sourcesContent":["import type { ExtendedChain, Route, Token } from '@lifi/sdk'\nimport {\n ChainType,\n convertQuoteToRoute,\n getContractCallsQuote,\n getRelayerQuote,\n getRoutes,\n LiFiErrorCode,\n parseUnits,\n} from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport {\n useChainTypeFromAddress,\n useEthereumContext,\n} from '@lifi/widget-provider'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useIntermediateRoutesStore } from '../stores/routes/useIntermediateRoutesStore.js'\nimport { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js'\nimport { defaultSlippage } from '../stores/settings/createSettingsStore.js'\nimport { useSettings } from '../stores/settings/useSettings.js'\nimport { WidgetEvent } from '../types/events.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { updateTokenInCache } from '../utils/token.js'\nimport { useChain } from './useChain.js'\nimport { useDebouncedWatch } from './useDebouncedWatch.js'\nimport { useGasRefuel } from './useGasRefuel.js'\nimport { useIsBatchingSupported } from './useIsBatchingSupported.js'\nimport { useSwapOnly } from './useSwapOnly.js'\nimport { useToken } from './useToken.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\nconst refetchTime = 60_000\n\ninterface RoutesProps {\n observableRoute?: Route\n}\n\nexport const useRoutes = ({\n observableRoute,\n}: RoutesProps = {}): {\n routes: Route[] | undefined\n isLoading: boolean\n isFetching: boolean\n isFetched: boolean\n dataUpdatedAt: number\n refetchTime: number\n refetch: () => void\n fromChain: ExtendedChain | undefined\n toChain: ExtendedChain | undefined\n queryKey: readonly unknown[]\n setReviewableRoute: (route: Route) => void\n} => {\n const {\n subvariant,\n subvariantOptions,\n contractTool,\n bridges,\n exchanges,\n fee,\n feeConfig,\n useRelayerRoutes,\n keyPrefix,\n } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const setExecutableRoute = useSetExecutableRoute()\n const queryClient = useQueryClient()\n const emitter = useWidgetEvents()\n const swapOnly = useSwapOnly()\n const {\n disabledBridges,\n disabledExchanges,\n enabledBridges,\n enabledExchanges,\n enabledAutoRefuel,\n routePriority,\n slippage,\n } = useSettings([\n 'disabledBridges',\n 'disabledExchanges',\n 'enabledBridges',\n 'enabledExchanges',\n 'enabledAutoRefuel',\n 'routePriority',\n 'slippage',\n ])\n const [fromTokenAmount] = useDebouncedWatch(500, 'fromAmount')\n const [\n fromChainId,\n fromTokenAddress,\n toAddress,\n toTokenAmount,\n toChainId,\n toTokenAddress,\n contractCalls,\n ] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toAddress',\n 'toAmount',\n 'toChain',\n 'toToken',\n 'contractCalls'\n )\n const { token: fromToken } = useToken(fromChainId, fromTokenAddress)\n const { token: toToken } = useToken(toChainId, toTokenAddress)\n const { chain: fromChain } = useChain(fromChainId)\n const { chain: toChain } = useChain(toChainId)\n const { enabled: enabledRefuel, fromAmount: gasRecommendationFromAmount } =\n useGasRefuel()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n const { isGaslessStep, disableMessageSigning } = useEthereumContext()\n const { account } = useAccount({ chainType: fromChain?.chainType })\n const { isBatchingSupported, isBatchingSupportedLoading } =\n useIsBatchingSupported(fromChain, account.address)\n\n const hasAmount = Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0\n\n const contractCallQuoteEnabled: boolean =\n subvariant === 'custom' ? Boolean(contractCalls && account.address) : true\n\n // When we bridge between ecosystems we need to be sure toAddress is set and has the same chainType as toChain\n // If toAddress is set, it must have the same chainType as toChain\n const hasToAddressAndChainTypeSatisfied: boolean =\n !!toChain &&\n !!toAddress &&\n getChainTypeFromAddress(toAddress) === toChain.chainType\n // We need to check for toAddress only if it is set\n const isToAddressSatisfied = toAddress\n ? hasToAddressAndChainTypeSatisfied\n : true\n\n // toAddress might be an empty string, but we need to pass undefined if there is no value\n const toWalletAddress = toAddress || undefined\n\n // We need to send the full allowed tools array if custom tool settings are applied\n const allowedBridges =\n bridges?.allow?.length || bridges?.deny?.length ? enabledBridges : undefined\n const allowedExchanges =\n exchanges?.allow?.length || exchanges?.deny?.length\n ? enabledExchanges\n : undefined\n const allowSwitchChain = sdkClient.config?.routeOptions?.allowSwitchChain\n\n const isEnabled =\n Boolean(Number(fromChain?.id)) &&\n Boolean(Number(toChain?.id)) &&\n Boolean(fromToken?.address) &&\n Boolean(toToken?.address) &&\n !Number.isNaN(slippage) &&\n hasAmount &&\n isToAddressSatisfied &&\n contractCallQuoteEnabled &&\n !isBatchingSupportedLoading\n\n // Some values should be strictly typed and isEnabled ensures that\n const queryKey = useMemo(\n () =>\n [\n getQueryKey('routes', keyPrefix),\n account.address,\n fromChain?.id as number,\n fromToken?.address as string,\n fromTokenAmount,\n toWalletAddress,\n toChain?.id as number,\n toToken?.address as string,\n toTokenAmount,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel && enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee || fee,\n disableMessageSigning,\n !!isBatchingSupported,\n observableRoute?.id,\n ] as const,\n [\n keyPrefix,\n account.address,\n fromChain?.id,\n fromToken?.address,\n fromTokenAmount,\n toWalletAddress,\n toChain?.id,\n toToken?.address,\n toTokenAmount,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel,\n enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee,\n fee,\n disableMessageSigning,\n isBatchingSupported,\n observableRoute?.id,\n ]\n )\n\n const { getIntermediateRoutes, setIntermediateRoutes } =\n useIntermediateRoutesStore()\n\n const { data, isLoading, isFetching, isFetched, dataUpdatedAt, refetch } =\n useQuery({\n queryKey,\n queryFn: async ({\n queryKey: [\n _,\n fromAddress,\n fromChainId,\n fromTokenAddress,\n fromTokenAmount,\n toAddress,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n contractCalls,\n slippage = defaultSlippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel,\n gasRecommendationFromAmount,\n fee,\n disableMessageSigning,\n isBatchingSupported,\n // _observableRouteId must be the last element in the query key\n _observableRouteId,\n ],\n signal,\n }) => {\n const fromAmount = parseUnits(fromTokenAmount, fromToken!.decimals)\n const toAmount = parseUnits(toTokenAmount, toToken!.decimals)\n const formattedSlippage = slippage\n ? Number.parseFloat(slippage) / 100\n : defaultSlippage\n\n const allowBridges = swapOnly\n ? []\n : observableRoute\n ? observableRoute.steps.flatMap((step) =>\n step.includedSteps.reduce((toolKeys, includedStep) => {\n if (includedStep.type === 'cross') {\n toolKeys.push(includedStep.toolDetails.key)\n }\n return toolKeys\n }, [] as string[])\n )\n : allowedBridges\n const allowExchanges = observableRoute\n ? observableRoute.steps.flatMap((step) =>\n step.includedSteps.reduce((toolKeys, includedStep) => {\n if (includedStep.type === 'swap') {\n toolKeys.push(includedStep.toolDetails.key)\n }\n return toolKeys\n }, [] as string[])\n )\n : allowedExchanges\n\n const calculatedFee = await feeConfig?.calculateFee?.({\n fromChain: fromChain!,\n toChain: toChain!,\n fromToken: fromToken!,\n toToken: toToken!,\n fromAddress,\n toAddress,\n fromAmount,\n toAmount,\n slippage: formattedSlippage,\n })\n\n if (subvariant === 'custom' && contractCalls && toAmount) {\n const contractCallQuote = await getContractCallsQuote(\n sdkClient,\n {\n // Contract calls are enabled only when fromAddress is set\n fromAddress: fromAddress as string,\n fromChain: fromChainId,\n fromToken: fromTokenAddress,\n toAmount: toAmount.toString(),\n toChain: toChainId,\n toToken: toTokenAddress,\n contractCalls,\n denyBridges: disabledBridges.length ? disabledBridges : undefined,\n denyExchanges: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n allowBridges,\n allowExchanges,\n toFallbackAddress: toAddress,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n },\n { signal }\n )\n\n contractCallQuote.action.toToken = toToken!\n\n const customStep =\n subvariant === 'custom'\n ? contractCallQuote.includedSteps?.find(\n (step) => step.type === 'custom'\n )\n : undefined\n\n if (customStep && contractTool) {\n const toolDetails = {\n key: contractTool.name,\n name: contractTool.name,\n logoURI: contractTool.logoURI,\n }\n customStep.toolDetails = toolDetails\n contractCallQuote.toolDetails = toolDetails\n }\n\n const route: Route = convertQuoteToRoute(contractCallQuote)\n\n return [route]\n }\n\n // Prevent sending a request for the same chain token combinations.\n // Exception: proceed anyway if subvariant is custom and subvariantOptions is deposit\n if (\n fromChainId === toChainId &&\n fromTokenAddress === toTokenAddress &&\n !(subvariant === 'custom' && subvariantOptions?.custom === 'deposit')\n ) {\n return\n }\n\n const isObservableRelayerRoute = observableRoute?.steps?.some(\n (step) => !!isGaslessStep?.(step, fromChain)\n )\n\n const shouldUseMainRoutes =\n !observableRoute || !isObservableRelayerRoute\n const shouldUseRelayerQuote =\n fromAddress &&\n fromChain?.chainType === ChainType.EVM &&\n fromChain.permit2 &&\n fromChain.permit2Proxy &&\n fromChain.relayerSupported &&\n fromChain.nativeToken.address !== fromTokenAddress &&\n useRelayerRoutes &&\n !isBatchingSupported &&\n (!observableRoute || isObservableRelayerRoute)\n\n const mainRoutesPromise = shouldUseMainRoutes\n ? getRoutes(\n sdkClient,\n {\n fromAddress,\n fromAmount: fromAmount.toString(),\n fromChainId,\n fromTokenAddress,\n toAddress,\n toChainId,\n toTokenAddress,\n fromAmountForGas:\n enabledRefuel && gasRecommendationFromAmount\n ? gasRecommendationFromAmount\n : undefined,\n options: {\n allowSwitchChain:\n subvariant === 'refuel' ? false : allowSwitchChain,\n bridges:\n allowBridges?.length || disabledBridges.length\n ? {\n allow: allowBridges,\n deny: disabledBridges.length\n ? disabledBridges\n : undefined,\n }\n : undefined,\n exchanges:\n allowExchanges?.length || disabledExchanges.length\n ? {\n allow: allowExchanges,\n deny: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n }\n : undefined,\n order: routePriority,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n executionType: disableMessageSigning ? 'transaction' : 'all',\n },\n },\n { signal }\n )\n : Promise.resolve(null)\n\n const relayerQuotePromise = shouldUseRelayerQuote\n ? getRelayerQuote(\n sdkClient,\n {\n fromAddress,\n fromAmount: fromAmount.toString(),\n fromChain: fromChainId,\n fromToken: fromTokenAddress,\n toAddress,\n toChain: toChainId,\n toToken: toTokenAddress,\n fromAmountForGas:\n enabledRefuel && gasRecommendationFromAmount\n ? gasRecommendationFromAmount\n : undefined,\n order: routePriority,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n ...(allowBridges?.length || disabledBridges.length\n ? {\n allowBridges: allowBridges,\n denyBridges: disabledBridges.length\n ? disabledBridges\n : undefined,\n }\n : undefined),\n ...(allowExchanges?.length || disabledExchanges.length\n ? {\n allowExchanges: allowExchanges,\n denyExchanges: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n }\n : undefined),\n },\n { signal }\n )\n .then(convertQuoteToRoute)\n .catch(() => null)\n : Promise.resolve(null)\n\n // Wait for the main routes to complete first\n const routesResult = await mainRoutesPromise\n\n if (routesResult?.routes[0] && fromAddress) {\n // Update local tokens cache to keep priceUSD in sync\n const { fromToken, toToken } = routesResult.routes[0]\n ;[fromToken, toToken].forEach((token) => {\n // Update main tokens cache (verified)\n queryClient.setQueriesData<TokensByChain>(\n { queryKey: [getQueryKey('tokens', keyPrefix)] },\n (data) => updateTokenInCache(data, token)\n )\n\n // Update search tokens cache (unverified) - matches any search query\n queryClient.setQueriesData<TokensByChain>(\n {\n queryKey: [getQueryKey('tokens-search', keyPrefix)],\n exact: false,\n },\n (data) => updateTokenInCache(data, token)\n )\n\n queryClient.setQueriesData<Token[]>(\n {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n fromAddress,\n token.chainId,\n ],\n },\n (data) => {\n if (data) {\n const clonedData = [...data]\n const index = clonedData.findIndex(\n (dataToken) => dataToken.address === token.address\n )\n if (index >= 0) {\n clonedData[index] = {\n ...clonedData[index],\n ...token,\n }\n }\n return clonedData\n }\n }\n )\n })\n }\n\n const initialRoutes = routesResult?.routes ?? []\n\n if (shouldUseRelayerQuote && initialRoutes.length) {\n setIntermediateRoutes(queryKey, initialRoutes)\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n // Return early if we're only using main routes\n } else if (shouldUseMainRoutes) {\n // If we don't need relayer quote, return the initial routes\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n return initialRoutes\n }\n\n const relayerRouteResult = await relayerQuotePromise\n // If we have a relayer route, add it to the routes array\n if (relayerRouteResult) {\n // Insert the relayer route at position 1 (after the first route)\n initialRoutes.splice(1, 0, relayerRouteResult)\n // Emit the updated routes\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n }\n\n return initialRoutes\n },\n enabled: isEnabled,\n staleTime: refetchTime,\n refetchInterval(query) {\n return Math.min(\n Math.abs(refetchTime - (Date.now() - query.state.dataUpdatedAt)),\n refetchTime\n )\n },\n retry(failureCount, error: any) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Route query failed:', { failureCount, error })\n }\n if (failureCount >= 3) {\n return false\n }\n if (error?.code === LiFiErrorCode.NotFound) {\n return false\n }\n return true\n },\n })\n\n const setReviewableRoute = useCallback(\n (route: Route) => {\n const queryDataKey = queryKey.toSpliced(queryKey.length - 1, 1, route.id)\n queryClient.setQueryData(queryDataKey, [route], {\n updatedAt: dataUpdatedAt || Date.now(),\n })\n setExecutableRoute(route)\n },\n [queryClient, dataUpdatedAt, setExecutableRoute, queryKey]\n )\n\n return {\n routes: data || getIntermediateRoutes(queryKey),\n isLoading: isEnabled && isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n fromChain,\n toChain,\n queryKey,\n setReviewableRoute,\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useRoutes.js","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"sourcesContent":["import type { ExtendedChain, Route, Token } from '@lifi/sdk'\nimport {\n ChainType,\n convertQuoteToRoute,\n getContractCallsQuote,\n getRelayerQuote,\n getRoutes,\n LiFiErrorCode,\n parseUnits,\n} from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport {\n useChainTypeFromAddress,\n useEthereumContext,\n} from '@lifi/widget-provider'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useIntermediateRoutesStore } from '../stores/routes/useIntermediateRoutesStore.js'\nimport { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js'\nimport { defaultSlippage } from '../stores/settings/createSettingsStore.js'\nimport { useSettings } from '../stores/settings/useSettings.js'\nimport { WidgetEvent } from '../types/events.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { updateTokenInCache } from '../utils/token.js'\nimport { useChain } from './useChain.js'\nimport { useDebouncedWatch } from './useDebouncedWatch.js'\nimport { useGasRefuel } from './useGasRefuel.js'\nimport { useIsBatchingSupported } from './useIsBatchingSupported.js'\nimport { useSwapOnly } from './useSwapOnly.js'\nimport { useToken } from './useToken.js'\nimport { useWidgetEvents } from './useWidgetEvents.js'\n\nconst refetchTime = 60_000\n\ninterface RoutesProps {\n observableRoute?: Route\n}\n\nexport const useRoutes = ({\n observableRoute,\n}: RoutesProps = {}): {\n routes: Route[] | undefined\n isLoading: boolean\n isFetching: boolean\n isFetched: boolean\n dataUpdatedAt: number\n refetchTime: number\n refetch: () => void\n fromChain: ExtendedChain | undefined\n toChain: ExtendedChain | undefined\n queryKey: readonly unknown[]\n setReviewableRoute: (route: Route) => void\n} => {\n const {\n subvariant,\n subvariantOptions,\n contractTool,\n bridges,\n exchanges,\n fee,\n feeConfig,\n useRelayerRoutes,\n keyPrefix,\n } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const setExecutableRoute = useSetExecutableRoute()\n const queryClient = useQueryClient()\n const emitter = useWidgetEvents()\n const swapOnly = useSwapOnly()\n const {\n disabledBridges,\n disabledExchanges,\n enabledBridges,\n enabledExchanges,\n enabledAutoRefuel,\n routePriority,\n slippage,\n } = useSettings([\n 'disabledBridges',\n 'disabledExchanges',\n 'enabledBridges',\n 'enabledExchanges',\n 'enabledAutoRefuel',\n 'routePriority',\n 'slippage',\n ])\n const [fromTokenAmount] = useDebouncedWatch(500, 'fromAmount')\n const [\n fromChainId,\n fromTokenAddress,\n toAddress,\n toTokenAmount,\n toChainId,\n toTokenAddress,\n contractCalls,\n ] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toAddress',\n 'toAmount',\n 'toChain',\n 'toToken',\n 'contractCalls'\n )\n const { token: fromToken } = useToken(fromChainId, fromTokenAddress)\n const { token: toToken } = useToken(toChainId, toTokenAddress)\n const { chain: fromChain } = useChain(fromChainId)\n const { chain: toChain } = useChain(toChainId)\n const { enabled: enabledRefuel, fromAmount: gasRecommendationFromAmount } =\n useGasRefuel()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n const { isGaslessStep, disableMessageSigning } = useEthereumContext()\n const { account } = useAccount({ chainType: fromChain?.chainType })\n const { isBatchingSupported, isBatchingSupportedLoading } =\n useIsBatchingSupported(fromChain, account.address)\n\n const hasAmount = Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0\n\n const contractCallQuoteEnabled: boolean =\n subvariant === 'custom' ? Boolean(contractCalls && account.address) : true\n\n // When we bridge between ecosystems we need to be sure toAddress is set and has the same chainType as toChain\n // If toAddress is set, it must have the same chainType as toChain\n const hasToAddressAndChainTypeSatisfied: boolean =\n !!toChain &&\n !!toAddress &&\n getChainTypeFromAddress(toAddress) === toChain.chainType\n // We need to check for toAddress only if it is set\n const isToAddressSatisfied = toAddress\n ? hasToAddressAndChainTypeSatisfied\n : true\n\n // toAddress might be an empty string, but we need to pass undefined if there is no value\n const toWalletAddress = toAddress || undefined\n\n // We need to send the full allowed tools array if custom tool settings are applied\n const allowedBridges =\n bridges?.allow?.length || bridges?.deny?.length ? enabledBridges : undefined\n const allowedExchanges =\n exchanges?.allow?.length || exchanges?.deny?.length\n ? enabledExchanges\n : undefined\n const allowSwitchChain = sdkClient.config?.routeOptions?.allowSwitchChain\n\n const isEnabled =\n Boolean(Number(fromChain?.id)) &&\n Boolean(Number(toChain?.id)) &&\n Boolean(fromToken?.address) &&\n Boolean(toToken?.address) &&\n !Number.isNaN(slippage) &&\n hasAmount &&\n isToAddressSatisfied &&\n contractCallQuoteEnabled &&\n !isBatchingSupportedLoading\n\n // Some values should be strictly typed and isEnabled ensures that\n const queryKey = useMemo(\n () =>\n [\n getQueryKey('routes', keyPrefix),\n account.address,\n fromChain?.id as number,\n fromToken?.address as string,\n fromTokenAmount,\n toWalletAddress,\n toChain?.id as number,\n toToken?.address as string,\n toTokenAmount,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel && enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee || fee,\n disableMessageSigning,\n !!isBatchingSupported,\n observableRoute?.id,\n ] as const,\n [\n keyPrefix,\n account.address,\n fromChain?.id,\n fromToken?.address,\n fromTokenAmount,\n toWalletAddress,\n toChain?.id,\n toToken?.address,\n toTokenAmount,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel,\n enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee,\n fee,\n disableMessageSigning,\n isBatchingSupported,\n observableRoute?.id,\n ]\n )\n\n const { getIntermediateRoutes, setIntermediateRoutes } =\n useIntermediateRoutesStore()\n\n const { data, isLoading, isFetching, isFetched, dataUpdatedAt, refetch } =\n useQuery({\n queryKey,\n queryFn: async ({\n queryKey: [\n _,\n fromAddress,\n fromChainId,\n fromTokenAddress,\n fromTokenAmount,\n toAddress,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n contractCalls,\n slippage = defaultSlippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n subvariant,\n allowSwitchChain,\n enabledRefuel,\n gasRecommendationFromAmount,\n fee,\n disableMessageSigning,\n isBatchingSupported,\n // _observableRouteId must be the last element in the query key\n _observableRouteId,\n ],\n signal,\n }) => {\n const fromAmount = parseUnits(fromTokenAmount, fromToken!.decimals)\n const toAmount = parseUnits(toTokenAmount, toToken!.decimals)\n const formattedSlippage = slippage\n ? Number.parseFloat(slippage) / 100\n : defaultSlippage\n\n const allowBridges = swapOnly\n ? []\n : observableRoute\n ? observableRoute.steps.flatMap((step) =>\n step.includedSteps.reduce((toolKeys, includedStep) => {\n if (includedStep.type === 'cross') {\n toolKeys.push(includedStep.toolDetails.key)\n }\n return toolKeys\n }, [] as string[])\n )\n : allowedBridges\n const allowExchanges = observableRoute\n ? observableRoute.steps.flatMap((step) =>\n step.includedSteps.reduce((toolKeys, includedStep) => {\n if (includedStep.type === 'swap') {\n toolKeys.push(includedStep.toolDetails.key)\n }\n return toolKeys\n }, [] as string[])\n )\n : allowedExchanges\n\n const calculatedFee = await feeConfig?.calculateFee?.({\n fromChain: fromChain!,\n toChain: toChain!,\n fromToken: fromToken!,\n toToken: toToken!,\n fromAddress,\n toAddress,\n fromAmount,\n toAmount,\n slippage: formattedSlippage,\n })\n\n if (subvariant === 'custom' && contractCalls && toAmount) {\n const contractCallQuote = await getContractCallsQuote(\n sdkClient,\n {\n // Contract calls are enabled only when fromAddress is set\n fromAddress: fromAddress as string,\n fromChain: fromChainId,\n fromToken: fromTokenAddress,\n toAmount: toAmount.toString(),\n toChain: toChainId,\n toToken: toTokenAddress,\n contractCalls,\n denyBridges: disabledBridges.length ? disabledBridges : undefined,\n denyExchanges: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n allowBridges,\n allowExchanges,\n toFallbackAddress: toAddress,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n },\n { signal }\n )\n\n contractCallQuote.action.toToken = toToken!\n\n const customStep =\n subvariant === 'custom'\n ? contractCallQuote.includedSteps?.find(\n (step) => step.type === 'custom'\n )\n : undefined\n\n if (customStep && contractTool) {\n const toolDetails = {\n key: contractTool.name,\n name: contractTool.name,\n logoURI: contractTool.logoURI,\n }\n customStep.toolDetails = toolDetails\n contractCallQuote.toolDetails = toolDetails\n }\n\n const route: Route = convertQuoteToRoute(contractCallQuote)\n\n return [route]\n }\n\n // Prevent sending a request for the same chain token combinations.\n // Exception: proceed anyway if subvariant is custom and subvariantOptions is deposit\n if (\n fromChainId === toChainId &&\n fromTokenAddress === toTokenAddress &&\n !(subvariant === 'custom' && subvariantOptions?.custom === 'deposit')\n ) {\n return\n }\n\n const isObservableRelayerRoute = observableRoute?.steps?.some(\n (step) => !!isGaslessStep?.(step, fromChain)\n )\n\n const shouldUseMainRoutes =\n !observableRoute || !isObservableRelayerRoute\n const shouldUseRelayerQuote =\n fromAddress &&\n fromChain?.chainType === ChainType.EVM &&\n fromChain.permit2 &&\n fromChain.permit2Proxy &&\n fromChain.relayerSupported &&\n fromChain.nativeToken.address !== fromTokenAddress &&\n useRelayerRoutes &&\n !isBatchingSupported &&\n (!observableRoute || isObservableRelayerRoute)\n\n const mainRoutesPromise = shouldUseMainRoutes\n ? getRoutes(\n sdkClient,\n {\n fromAddress,\n fromAmount: fromAmount.toString(),\n fromChainId,\n fromTokenAddress,\n toAddress,\n toChainId,\n toTokenAddress,\n fromAmountForGas:\n enabledRefuel && gasRecommendationFromAmount\n ? gasRecommendationFromAmount\n : undefined,\n options: {\n allowSwitchChain:\n subvariant === 'refuel' ? false : allowSwitchChain,\n bridges:\n allowBridges?.length || disabledBridges.length\n ? {\n allow: allowBridges,\n deny: disabledBridges.length\n ? disabledBridges\n : undefined,\n }\n : undefined,\n exchanges:\n allowExchanges?.length || disabledExchanges.length\n ? {\n allow: allowExchanges,\n deny: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n }\n : undefined,\n order: routePriority,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n executionType: disableMessageSigning ? 'transaction' : 'all',\n },\n },\n { signal }\n )\n : Promise.resolve(null)\n\n const relayerQuotePromise = shouldUseRelayerQuote\n ? getRelayerQuote(\n sdkClient,\n {\n fromAddress,\n fromAmount: fromAmount.toString(),\n fromChain: fromChainId,\n fromToken: fromTokenAddress,\n toAddress,\n toChain: toChainId,\n toToken: toTokenAddress,\n fromAmountForGas:\n enabledRefuel && gasRecommendationFromAmount\n ? gasRecommendationFromAmount\n : undefined,\n order: routePriority,\n slippage: formattedSlippage,\n fee: calculatedFee || fee,\n ...(allowBridges?.length || disabledBridges.length\n ? {\n allowBridges: allowBridges,\n denyBridges: disabledBridges.length\n ? disabledBridges\n : undefined,\n }\n : undefined),\n ...(allowExchanges?.length || disabledExchanges.length\n ? {\n allowExchanges: allowExchanges,\n denyExchanges: disabledExchanges.length\n ? disabledExchanges\n : undefined,\n }\n : undefined),\n },\n { signal }\n )\n .then(convertQuoteToRoute)\n .catch(() => null)\n : Promise.resolve(null)\n\n // Wait for the main routes to complete first\n const routesResult = await mainRoutesPromise\n\n if (routesResult?.routes[0] && fromAddress) {\n // Update local tokens cache to keep priceUSD in sync\n const { fromToken, toToken } = routesResult.routes[0]\n ;[fromToken, toToken].forEach((token) => {\n // Update main tokens cache (verified)\n queryClient.setQueriesData<TokensByChain>(\n { queryKey: [getQueryKey('tokens', keyPrefix)] },\n (data) => updateTokenInCache(data, token)\n )\n\n // Update search tokens cache (unverified) - matches any search query\n queryClient.setQueriesData<TokensByChain>(\n {\n queryKey: [getQueryKey('tokens-search', keyPrefix)],\n exact: false,\n },\n (data) => updateTokenInCache(data, token)\n )\n\n queryClient.setQueriesData<Token[]>(\n {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n fromAddress,\n token.chainId,\n ],\n },\n (data) => {\n if (data) {\n const clonedData = [...data]\n const index = clonedData.findIndex(\n (dataToken) => dataToken.address === token.address\n )\n if (index >= 0) {\n clonedData[index] = {\n ...clonedData[index],\n ...token,\n }\n }\n return clonedData\n }\n }\n )\n })\n }\n\n const initialRoutes = routesResult?.routes ?? []\n\n if (shouldUseRelayerQuote && initialRoutes.length) {\n setIntermediateRoutes(queryKey, initialRoutes)\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n // Return early if we're only using main routes\n } else if (shouldUseMainRoutes) {\n // If we don't need relayer quote, return the initial routes\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n return initialRoutes\n }\n\n const relayerRouteResult = await relayerQuotePromise\n // If we have a relayer route, add it to the routes array\n if (relayerRouteResult) {\n // Insert the relayer route at position 1 (after the first route)\n initialRoutes.splice(1, 0, relayerRouteResult)\n // Emit the updated routes\n emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)\n }\n\n return initialRoutes\n },\n enabled: isEnabled,\n staleTime: refetchTime,\n refetchInterval(query) {\n return Math.min(\n Math.abs(refetchTime - (Date.now() - query.state.dataUpdatedAt)),\n refetchTime\n )\n },\n retry(failureCount, error: any) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Route query failed:', { failureCount, error })\n }\n if (failureCount >= 3) {\n return false\n }\n if (error?.code === LiFiErrorCode.NotFound) {\n return false\n }\n return true\n },\n })\n\n const setReviewableRoute = useCallback(\n (route: Route) => {\n const queryDataKey = queryKey.toSpliced(queryKey.length - 1, 1, route.id)\n queryClient.setQueryData(queryDataKey, [route], {\n updatedAt: dataUpdatedAt || Date.now(),\n })\n setExecutableRoute(route)\n },\n [queryClient, dataUpdatedAt, setExecutableRoute, queryKey]\n )\n\n return {\n routes: data || getIntermediateRoutes(queryKey),\n isLoading: isEnabled && isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n fromChain,\n toChain,\n queryKey,\n setReviewableRoute,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScrollableContainer.js","names":[],"sources":["../../../src/hooks/useScrollableContainer.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useState } from 'react'\nimport { getScrollableContainer } from '../utils/elements.js'\nimport { useDefaultElementId } from './useDefaultElementId.js'\n\nexport const useGetScrollableContainer = (): (() => HTMLElement | null) => {\n const elementId = useDefaultElementId() ?? ''\n const getContainer = useCallback(\n () => getScrollableContainer(elementId),\n [elementId]\n )\n\n return getContainer\n}\n\nexport const useScrollableContainer = (\n elementId: string\n): HTMLElement | null => {\n const [containerElement, setContainerElement] = useState(() =>\n getScrollableContainer(elementId)\n )\n\n useLayoutEffect(() => {\n if (!containerElement) {\n setContainerElement(getScrollableContainer(elementId))\n }\n }, [containerElement, elementId])\n\n return containerElement\n}\n\nexport const useScrollableOverflowHidden = (): void => {\n const elementId = useDefaultElementId() ?? ''\n useLayoutEffect(() => {\n const element = getScrollableContainer(elementId)\n if (element) {\n element.style.overflowY = 'hidden'\n }\n return () => {\n if (element) {\n element.style.overflowY = 'auto'\n }\n }\n }, [elementId])\n}\n"],"mappings":";;;;AAIA,MAAa,kCAA8D;CACzE,MAAM,YAAY,qBAAqB,IAAI;AAM3C,QALqB,kBACb,uBAAuB,UAAU,EACvC,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"useScrollableContainer.js","names":[],"sources":["../../../src/hooks/useScrollableContainer.ts"],"sourcesContent":["import { useCallback, useLayoutEffect, useState } from 'react'\nimport { getScrollableContainer } from '../utils/elements.js'\nimport { useDefaultElementId } from './useDefaultElementId.js'\n\nexport const useGetScrollableContainer = (): (() => HTMLElement | null) => {\n const elementId = useDefaultElementId() ?? ''\n const getContainer = useCallback(\n () => getScrollableContainer(elementId),\n [elementId]\n )\n\n return getContainer\n}\n\nexport const useScrollableContainer = (\n elementId: string\n): HTMLElement | null => {\n const [containerElement, setContainerElement] = useState(() =>\n getScrollableContainer(elementId)\n )\n\n useLayoutEffect(() => {\n if (!containerElement) {\n setContainerElement(getScrollableContainer(elementId))\n }\n }, [containerElement, elementId])\n\n return containerElement\n}\n\nexport const useScrollableOverflowHidden = (): void => {\n const elementId = useDefaultElementId() ?? ''\n useLayoutEffect(() => {\n const element = getScrollableContainer(elementId)\n if (element) {\n element.style.overflowY = 'hidden'\n }\n return () => {\n if (element) {\n element.style.overflowY = 'auto'\n }\n }\n }, [elementId])\n}\n"],"mappings":";;;;AAIA,MAAa,kCAA8D;CACzE,MAAM,YAAY,qBAAqB,IAAI;AAM3C,QALqB,kBACb,uBAAuB,UAAU,EACvC,CAAC,UAAU,CAGM;;AAGrB,MAAa,0BACX,cACuB;CACvB,MAAM,CAAC,kBAAkB,uBAAuB,eAC9C,uBAAuB,UAAU,CAClC;AAED,uBAAsB;AACpB,MAAI,CAAC,iBACH,qBAAoB,uBAAuB,UAAU,CAAC;IAEvD,CAAC,kBAAkB,UAAU,CAAC;AAEjC,QAAO;;AAGT,MAAa,oCAA0C;CACrD,MAAM,YAAY,qBAAqB,IAAI;AAC3C,uBAAsB;EACpB,MAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,QACF,SAAQ,MAAM,YAAY;AAE5B,eAAa;AACX,OAAI,QACF,SAAQ,MAAM,YAAY;;IAG7B,CAAC,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSwapOnly.js","names":[],"sources":["../../../src/hooks/useSwapOnly.ts"],"sourcesContent":["import { useSplitSubvariantStore } from '../stores/settings/useSplitSubvariantStore.js'\n\nexport const useSwapOnly = (): boolean => {\n const state = useSplitSubvariantStore((state) => state.state)\n return state === 'swap'\n}\n"],"mappings":";;AAEA,MAAa,oBAA6B;AAExC,QADc,yBAAyB,UAAU,MAAM,
|
|
1
|
+
{"version":3,"file":"useSwapOnly.js","names":[],"sources":["../../../src/hooks/useSwapOnly.ts"],"sourcesContent":["import { useSplitSubvariantStore } from '../stores/settings/useSplitSubvariantStore.js'\n\nexport const useSwapOnly = (): boolean => {\n const state = useSplitSubvariantStore((state) => state.state)\n return state === 'swap'\n}\n"],"mappings":";;AAEA,MAAa,oBAA6B;AAExC,QADc,yBAAyB,UAAU,MAAM,MAC3C,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToAddressAutoPopulate.js","names":[],"sources":["../../../src/hooks/useToAddressAutoPopulate.ts"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useCallback } from 'react'\nimport { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { useFieldActions } from '../stores/form/useFieldActions.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\ntype UpdateToAddressArgs = {\n formType: FormType\n selectedToAddress?: string\n selectedChainId?: number\n selectedOppositeTokenAddress?: string\n selectedOppositeChainId?: number\n}\n\n/**\n * Automatically populates toAddress field if bridging across ecosystems and compatible wallet is connected\n */\nexport const useToAddressAutoPopulate = (): ((\n args: UpdateToAddressArgs\n) => string | undefined) => {\n const { setFieldValue } = useFieldActions()\n const { setSelectedBookmark } = useBookmarkActions()\n const { getChainById } = useAvailableChains()\n const { accounts } = useAccount()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n\n return useCallback(\n ({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n }: UpdateToAddressArgs) => {\n if (\n !selectedOppositeTokenAddress ||\n !selectedOppositeChainId ||\n !selectedChainId ||\n !accounts?.length\n ) {\n return\n }\n const selectedChain = getChainById?.(selectedChainId)\n const selectedOppositeChain = getChainById?.(selectedOppositeChainId)\n // Proceed if both chains are defined and of different ecosystem types (indicating cross-ecosystem bridging)\n if (\n !selectedChain ||\n !selectedOppositeChain ||\n selectedChain.chainType === selectedOppositeChain.chainType\n ) {\n return\n }\n // Identify the destination chain type based on the bridge direction ('from' or 'to')\n const destinationChainType =\n formType === 'from'\n ? selectedOppositeChain.chainType\n : selectedChain.chainType\n // If toAddress is already selected, verify that it matches the destination chain type\n if (selectedToAddress) {\n const selectedToAddressChainType =\n getChainTypeFromAddress(selectedToAddress)\n if (destinationChainType === selectedToAddressChainType) {\n return\n }\n }\n // Find connected account compatible with the destination chain type\n const destinationAccount = accounts?.find(\n (account) => account.chainType === destinationChainType\n )\n // If a compatible destination account is found, set toAddress as if selecting it from the \"Send to Wallet\" connected wallets page\n if (destinationAccount?.address) {\n setFieldValue('toAddress', destinationAccount.address, {\n isDirty: false,\n isTouched: true,\n })\n setSelectedBookmark({\n name: destinationAccount.connector?.name,\n address: destinationAccount.address,\n chainType: destinationAccount.chainType,\n isConnectedAccount: true,\n })\n return destinationAccount.address\n }\n },\n [\n accounts,\n getChainById,\n setFieldValue,\n setSelectedBookmark,\n getChainTypeFromAddress,\n ]\n )\n}\n"],"mappings":";;;;;;;;;;AAmBA,MAAa,iCAEe;CAC1B,MAAM,EAAE,kBAAkB,iBAAiB;CAC3C,MAAM,EAAE,wBAAwB,oBAAoB;CACpD,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,EAAE,4BAA4B,yBAAyB;AAE7D,QAAO,aACJ,EACC,UACA,mBACA,iBACA,8BACA,8BACyB;AACzB,MACE,CAAC,gCACD,CAAC,2BACD,CAAC,mBACD,CAAC,UAAU,OAEX;EAEF,MAAM,gBAAgB,eAAe,gBAAgB;EACrD,MAAM,wBAAwB,eAAe,wBAAwB;AAErE,MACE,CAAC,iBACD,CAAC,yBACD,cAAc,cAAc,sBAAsB,UAElD;EAGF,MAAM,uBACJ,aAAa,SACT,sBAAsB,YACtB,cAAc;AAEpB,MAAI;OAGE,yBADF,wBAAwB,
|
|
1
|
+
{"version":3,"file":"useToAddressAutoPopulate.js","names":[],"sources":["../../../src/hooks/useToAddressAutoPopulate.ts"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useCallback } from 'react'\nimport { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { useFieldActions } from '../stores/form/useFieldActions.js'\nimport { useAvailableChains } from './useAvailableChains.js'\n\ntype UpdateToAddressArgs = {\n formType: FormType\n selectedToAddress?: string\n selectedChainId?: number\n selectedOppositeTokenAddress?: string\n selectedOppositeChainId?: number\n}\n\n/**\n * Automatically populates toAddress field if bridging across ecosystems and compatible wallet is connected\n */\nexport const useToAddressAutoPopulate = (): ((\n args: UpdateToAddressArgs\n) => string | undefined) => {\n const { setFieldValue } = useFieldActions()\n const { setSelectedBookmark } = useBookmarkActions()\n const { getChainById } = useAvailableChains()\n const { accounts } = useAccount()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n\n return useCallback(\n ({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n }: UpdateToAddressArgs) => {\n if (\n !selectedOppositeTokenAddress ||\n !selectedOppositeChainId ||\n !selectedChainId ||\n !accounts?.length\n ) {\n return\n }\n const selectedChain = getChainById?.(selectedChainId)\n const selectedOppositeChain = getChainById?.(selectedOppositeChainId)\n // Proceed if both chains are defined and of different ecosystem types (indicating cross-ecosystem bridging)\n if (\n !selectedChain ||\n !selectedOppositeChain ||\n selectedChain.chainType === selectedOppositeChain.chainType\n ) {\n return\n }\n // Identify the destination chain type based on the bridge direction ('from' or 'to')\n const destinationChainType =\n formType === 'from'\n ? selectedOppositeChain.chainType\n : selectedChain.chainType\n // If toAddress is already selected, verify that it matches the destination chain type\n if (selectedToAddress) {\n const selectedToAddressChainType =\n getChainTypeFromAddress(selectedToAddress)\n if (destinationChainType === selectedToAddressChainType) {\n return\n }\n }\n // Find connected account compatible with the destination chain type\n const destinationAccount = accounts?.find(\n (account) => account.chainType === destinationChainType\n )\n // If a compatible destination account is found, set toAddress as if selecting it from the \"Send to Wallet\" connected wallets page\n if (destinationAccount?.address) {\n setFieldValue('toAddress', destinationAccount.address, {\n isDirty: false,\n isTouched: true,\n })\n setSelectedBookmark({\n name: destinationAccount.connector?.name,\n address: destinationAccount.address,\n chainType: destinationAccount.chainType,\n isConnectedAccount: true,\n })\n return destinationAccount.address\n }\n },\n [\n accounts,\n getChainById,\n setFieldValue,\n setSelectedBookmark,\n getChainTypeFromAddress,\n ]\n )\n}\n"],"mappings":";;;;;;;;;;AAmBA,MAAa,iCAEe;CAC1B,MAAM,EAAE,kBAAkB,iBAAiB;CAC3C,MAAM,EAAE,wBAAwB,oBAAoB;CACpD,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,EAAE,4BAA4B,yBAAyB;AAE7D,QAAO,aACJ,EACC,UACA,mBACA,iBACA,8BACA,8BACyB;AACzB,MACE,CAAC,gCACD,CAAC,2BACD,CAAC,mBACD,CAAC,UAAU,OAEX;EAEF,MAAM,gBAAgB,eAAe,gBAAgB;EACrD,MAAM,wBAAwB,eAAe,wBAAwB;AAErE,MACE,CAAC,iBACD,CAAC,yBACD,cAAc,cAAc,sBAAsB,UAElD;EAGF,MAAM,uBACJ,aAAa,SACT,sBAAsB,YACtB,cAAc;AAEpB,MAAI;OAGE,yBADF,wBAAwB,kBAC6B,CACrD;;EAIJ,MAAM,qBAAqB,UAAU,MAClC,YAAY,QAAQ,cAAc,qBACpC;AAED,MAAI,oBAAoB,SAAS;AAC/B,iBAAc,aAAa,mBAAmB,SAAS;IACrD,SAAS;IACT,WAAW;IACZ,CAAC;AACF,uBAAoB;IAClB,MAAM,mBAAmB,WAAW;IACpC,SAAS,mBAAmB;IAC5B,WAAW,mBAAmB;IAC9B,oBAAoB;IACrB,CAAC;AACF,UAAO,mBAAmB;;IAG9B;EACE;EACA;EACA;EACA;EACA;EACD,CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
-
import
|
|
2
|
+
import "../types/widget.js";
|
|
3
3
|
import { useFieldValues } from "../stores/form/useFieldValues.js";
|
|
4
4
|
import { useChain } from "./useChain.js";
|
|
5
5
|
import { useIsContractAddress } from "./useIsContractAddress.js";
|
|
@@ -21,7 +21,7 @@ const useToAddressRequirements = (route) => {
|
|
|
21
21
|
const { isContractAddress: isToContractAddress, isLoading: isToContractLoading, isFetched: isToContractFetched } = useIsContractAddress(toAddress, toChainId, toChain?.chainType);
|
|
22
22
|
const isDifferentChainType = fromChain && toChain && fromChain.chainType !== toChain.chainType;
|
|
23
23
|
const fromContractCodeHasDelegationIndicator = isDelegationDesignatorCode?.(fromContractCode);
|
|
24
|
-
const requiredToAddress = Boolean((isDifferentChainType || isFromContractAddress && fromChainId !== toChainId && !fromContractCodeHasDelegationIndicator || requiredUI?.includes(
|
|
24
|
+
const requiredToAddress = Boolean((isDifferentChainType || isFromContractAddress && fromChainId !== toChainId && !fromContractCodeHasDelegationIndicator || requiredUI?.includes("toAddress")) && !hiddenUI?.includes("toAddress"));
|
|
25
25
|
const accountNotDeployedAtDestination = Boolean(isFromContractAddress && !fromContractCodeHasDelegationIndicator && !isToContractAddress && fromAddress?.toLowerCase() === toAddress?.toLowerCase());
|
|
26
26
|
const accountDeployedAtDestination = Boolean(isFromContractAddress && isToContractAddress && !fromContractCodeHasDelegationIndicator && fromAddress?.toLowerCase() === toAddress?.toLowerCase());
|
|
27
27
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToAddressRequirements.js","names":[],"sources":["../../../src/hooks/useToAddressRequirements.ts"],"sourcesContent":["import type { ChainType, RouteExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport { useChain } from '../hooks/useChain.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { HiddenUI, RequiredUI } from '../types/widget.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\n\nexport const useToAddressRequirements = (\n route?: RouteExtended\n): {\n requiredToAddress: boolean\n requiredToChainType: ChainType | undefined\n accountNotDeployedAtDestination: boolean\n accountDeployedAtDestination: boolean\n toAddress: string | undefined\n isFromContractAddress: boolean | undefined\n isToContractAddress: boolean | undefined\n isLoading: boolean\n isFetched: boolean\n} => {\n const { requiredUI, hiddenUI } = useWidgetConfig()\n const [formFromChainId, formToChainId, formToAddress] = useFieldValues(\n 'fromChain',\n 'toChain',\n 'toAddress'\n )\n const { isDelegationDesignatorCode } = useEthereumContext()\n\n const fromChainId = route?.fromChainId ?? formFromChainId\n const toChainId = route?.toChainId ?? formToChainId\n\n const { chain: fromChain } = useChain(fromChainId)\n const { chain: toChain } = useChain(toChainId)\n const { account } = useAccount({\n chainType: fromChain?.chainType,\n })\n\n const fromAddress = route?.fromAddress ?? account.address\n const toAddress = route\n ? route.fromAddress !== route.toAddress\n ? route.toAddress\n : formToAddress\n : formToAddress\n\n const {\n isContractAddress: isFromContractAddress,\n contractCode: fromContractCode,\n isLoading: isFromContractLoading,\n isFetched: isFromContractFetched,\n } = useIsContractAddress(account.address, fromChainId, account.chainType)\n const {\n isContractAddress: isToContractAddress,\n isLoading: isToContractLoading,\n isFetched: isToContractFetched,\n } = useIsContractAddress(toAddress, toChainId, toChain?.chainType)\n\n const isDifferentChainType =\n fromChain && toChain && fromChain.chainType !== toChain.chainType\n\n // We don't want to block transfers for EIP-7702 accounts since they are designed\n // to maintain EOA-like properties while delegating execution.\n const fromContractCodeHasDelegationIndicator =\n isDelegationDesignatorCode?.(fromContractCode)\n\n const isCrossChainContractAddress =\n isFromContractAddress &&\n fromChainId !== toChainId &&\n !fromContractCodeHasDelegationIndicator\n\n const requiredToAddress = Boolean(\n (isDifferentChainType ||\n isCrossChainContractAddress ||\n requiredUI?.includes(RequiredUI.ToAddress)) &&\n !hiddenUI?.includes(HiddenUI.ToAddress)\n )\n\n const accountNotDeployedAtDestination = Boolean(\n isFromContractAddress &&\n !fromContractCodeHasDelegationIndicator &&\n !isToContractAddress &&\n fromAddress?.toLowerCase() === toAddress?.toLowerCase()\n )\n\n const accountDeployedAtDestination = Boolean(\n isFromContractAddress &&\n isToContractAddress &&\n !fromContractCodeHasDelegationIndicator &&\n fromAddress?.toLowerCase() === toAddress?.toLowerCase()\n )\n\n return {\n requiredToAddress,\n requiredToChainType: toChain?.chainType,\n accountNotDeployedAtDestination,\n accountDeployedAtDestination,\n toAddress,\n isFromContractAddress,\n isToContractAddress,\n isLoading: isFromContractLoading || isToContractLoading,\n isFetched: isFromContractFetched && isToContractFetched,\n }\n}\n"],"mappings":";;;;;;;;AASA,MAAa,4BACX,UAWG;CACH,MAAM,EAAE,YAAY,aAAa,iBAAiB;CAClD,MAAM,CAAC,iBAAiB,eAAe,iBAAiB,eACtD,aACA,WACA,YACD;CACD,MAAM,EAAE,+BAA+B,oBAAoB;CAE3D,MAAM,cAAc,OAAO,eAAe;CAC1C,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,EAAE,OAAO,cAAc,SAAS,YAAY;CAClD,MAAM,EAAE,OAAO,YAAY,SAAS,UAAU;CAC9C,MAAM,EAAE,YAAY,WAAW,EAC7B,WAAW,WAAW,WACvB,CAAC;CAEF,MAAM,cAAc,OAAO,eAAe,QAAQ;CAClD,MAAM,YAAY,QACd,MAAM,gBAAgB,MAAM,YAC1B,MAAM,YACN,gBACF;CAEJ,MAAM,EACJ,mBAAmB,uBACnB,cAAc,kBACd,WAAW,uBACX,WAAW,0BACT,qBAAqB,QAAQ,SAAS,aAAa,QAAQ,UAAU;CACzE,MAAM,EACJ,mBAAmB,qBACnB,WAAW,qBACX,WAAW,wBACT,qBAAqB,WAAW,WAAW,SAAS,UAAU;CAElE,MAAM,uBACJ,aAAa,WAAW,UAAU,cAAc,QAAQ;CAI1D,MAAM,yCACJ,6BAA6B,iBAAiB;CAOhD,MAAM,oBAAoB,SACvB,wBALD,yBACA,gBAAgB,aAChB,CAAC,0CAKC,YAAY,
|
|
1
|
+
{"version":3,"file":"useToAddressRequirements.js","names":[],"sources":["../../../src/hooks/useToAddressRequirements.ts"],"sourcesContent":["import type { ChainType, RouteExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport { useChain } from '../hooks/useChain.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { HiddenUI, RequiredUI } from '../types/widget.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\n\nexport const useToAddressRequirements = (\n route?: RouteExtended\n): {\n requiredToAddress: boolean\n requiredToChainType: ChainType | undefined\n accountNotDeployedAtDestination: boolean\n accountDeployedAtDestination: boolean\n toAddress: string | undefined\n isFromContractAddress: boolean | undefined\n isToContractAddress: boolean | undefined\n isLoading: boolean\n isFetched: boolean\n} => {\n const { requiredUI, hiddenUI } = useWidgetConfig()\n const [formFromChainId, formToChainId, formToAddress] = useFieldValues(\n 'fromChain',\n 'toChain',\n 'toAddress'\n )\n const { isDelegationDesignatorCode } = useEthereumContext()\n\n const fromChainId = route?.fromChainId ?? formFromChainId\n const toChainId = route?.toChainId ?? formToChainId\n\n const { chain: fromChain } = useChain(fromChainId)\n const { chain: toChain } = useChain(toChainId)\n const { account } = useAccount({\n chainType: fromChain?.chainType,\n })\n\n const fromAddress = route?.fromAddress ?? account.address\n const toAddress = route\n ? route.fromAddress !== route.toAddress\n ? route.toAddress\n : formToAddress\n : formToAddress\n\n const {\n isContractAddress: isFromContractAddress,\n contractCode: fromContractCode,\n isLoading: isFromContractLoading,\n isFetched: isFromContractFetched,\n } = useIsContractAddress(account.address, fromChainId, account.chainType)\n const {\n isContractAddress: isToContractAddress,\n isLoading: isToContractLoading,\n isFetched: isToContractFetched,\n } = useIsContractAddress(toAddress, toChainId, toChain?.chainType)\n\n const isDifferentChainType =\n fromChain && toChain && fromChain.chainType !== toChain.chainType\n\n // We don't want to block transfers for EIP-7702 accounts since they are designed\n // to maintain EOA-like properties while delegating execution.\n const fromContractCodeHasDelegationIndicator =\n isDelegationDesignatorCode?.(fromContractCode)\n\n const isCrossChainContractAddress =\n isFromContractAddress &&\n fromChainId !== toChainId &&\n !fromContractCodeHasDelegationIndicator\n\n const requiredToAddress = Boolean(\n (isDifferentChainType ||\n isCrossChainContractAddress ||\n requiredUI?.includes(RequiredUI.ToAddress)) &&\n !hiddenUI?.includes(HiddenUI.ToAddress)\n )\n\n const accountNotDeployedAtDestination = Boolean(\n isFromContractAddress &&\n !fromContractCodeHasDelegationIndicator &&\n !isToContractAddress &&\n fromAddress?.toLowerCase() === toAddress?.toLowerCase()\n )\n\n const accountDeployedAtDestination = Boolean(\n isFromContractAddress &&\n isToContractAddress &&\n !fromContractCodeHasDelegationIndicator &&\n fromAddress?.toLowerCase() === toAddress?.toLowerCase()\n )\n\n return {\n requiredToAddress,\n requiredToChainType: toChain?.chainType,\n accountNotDeployedAtDestination,\n accountDeployedAtDestination,\n toAddress,\n isFromContractAddress,\n isToContractAddress,\n isLoading: isFromContractLoading || isToContractLoading,\n isFetched: isFromContractFetched && isToContractFetched,\n }\n}\n"],"mappings":";;;;;;;;AASA,MAAa,4BACX,UAWG;CACH,MAAM,EAAE,YAAY,aAAa,iBAAiB;CAClD,MAAM,CAAC,iBAAiB,eAAe,iBAAiB,eACtD,aACA,WACA,YACD;CACD,MAAM,EAAE,+BAA+B,oBAAoB;CAE3D,MAAM,cAAc,OAAO,eAAe;CAC1C,MAAM,YAAY,OAAO,aAAa;CAEtC,MAAM,EAAE,OAAO,cAAc,SAAS,YAAY;CAClD,MAAM,EAAE,OAAO,YAAY,SAAS,UAAU;CAC9C,MAAM,EAAE,YAAY,WAAW,EAC7B,WAAW,WAAW,WACvB,CAAC;CAEF,MAAM,cAAc,OAAO,eAAe,QAAQ;CAClD,MAAM,YAAY,QACd,MAAM,gBAAgB,MAAM,YAC1B,MAAM,YACN,gBACF;CAEJ,MAAM,EACJ,mBAAmB,uBACnB,cAAc,kBACd,WAAW,uBACX,WAAW,0BACT,qBAAqB,QAAQ,SAAS,aAAa,QAAQ,UAAU;CACzE,MAAM,EACJ,mBAAmB,qBACnB,WAAW,qBACX,WAAW,wBACT,qBAAqB,WAAW,WAAW,SAAS,UAAU;CAElE,MAAM,uBACJ,aAAa,WAAW,UAAU,cAAc,QAAQ;CAI1D,MAAM,yCACJ,6BAA6B,iBAAiB;CAOhD,MAAM,oBAAoB,SACvB,wBALD,yBACA,gBAAgB,aAChB,CAAC,0CAKC,YAAY,SAAA,YAA8B,KAC1C,CAAC,UAAU,SAAA,YAA4B,CAC1C;CAED,MAAM,kCAAkC,QACtC,yBACE,CAAC,0CACD,CAAC,uBACD,aAAa,aAAa,KAAK,WAAW,aAAa,CAC1D;CAED,MAAM,+BAA+B,QACnC,yBACE,uBACA,CAAC,0CACD,aAAa,aAAa,KAAK,WAAW,aAAa,CAC1D;AAED,QAAO;EACL;EACA,qBAAqB,SAAS;EAC9B;EACA;EACA;EACA;EACA;EACA,WAAW,yBAAyB;EACpC,WAAW,yBAAyB;EACrC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
-
import
|
|
2
|
+
import "../types/widget.js";
|
|
3
3
|
import { useBookmarkActions } from "../stores/bookmarks/useBookmarkActions.js";
|
|
4
4
|
import { useBookmarks } from "../stores/bookmarks/useBookmarks.js";
|
|
5
5
|
import { useFieldActions } from "../stores/form/useFieldActions.js";
|
|
@@ -11,7 +11,7 @@ const useToAddressReset = () => {
|
|
|
11
11
|
const { selectedBookmark } = useBookmarks();
|
|
12
12
|
const { setSelectedBookmark } = useBookmarkActions();
|
|
13
13
|
return { tryResetToAddress: useCallback((toChain) => {
|
|
14
|
-
const requiredToAddress = requiredUI?.includes(
|
|
14
|
+
const requiredToAddress = requiredUI?.includes("toAddress");
|
|
15
15
|
const bookmarkSatisfiesToChainType = selectedBookmark?.chainType === toChain?.chainType;
|
|
16
16
|
if (!requiredToAddress && !bookmarkSatisfiesToChainType) {
|
|
17
17
|
setFieldValue("toAddress", "", { isTouched: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToAddressReset.js","names":[],"sources":["../../../src/hooks/useToAddressReset.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useCallback } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'\nimport { useBookmarks } from '../stores/bookmarks/useBookmarks.js'\nimport { useFieldActions } from '../stores/form/useFieldActions.js'\nimport { RequiredUI } from '../types/widget.js'\n\nexport const useToAddressReset = (): {\n tryResetToAddress: (toChain: ExtendedChain) => void\n} => {\n const { requiredUI } = useWidgetConfig()\n const { setFieldValue } = useFieldActions()\n const { selectedBookmark } = useBookmarks()\n const { setSelectedBookmark } = useBookmarkActions()\n\n const tryResetToAddress = useCallback(\n (toChain: ExtendedChain) => {\n const requiredToAddress = requiredUI?.includes(RequiredUI.ToAddress)\n\n const bookmarkSatisfiesToChainType =\n selectedBookmark?.chainType === toChain?.chainType\n\n const shouldResetToAddress =\n !requiredToAddress && !bookmarkSatisfiesToChainType\n\n // We reset toAddress on each chain change if it's no longer required, ensuring that\n // switching chain types doesn't leave a stale toAddress from a different ecosystem.\n if (shouldResetToAddress) {\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n },\n [setFieldValue, setSelectedBookmark, requiredUI, selectedBookmark]\n )\n\n return {\n tryResetToAddress,\n }\n}\n"],"mappings":";;;;;;;AAQA,MAAa,0BAER;CACH,MAAM,EAAE,eAAe,iBAAiB;CACxC,MAAM,EAAE,kBAAkB,iBAAiB;CAC3C,MAAM,EAAE,qBAAqB,cAAc;CAC3C,MAAM,EAAE,wBAAwB,oBAAoB;AAsBpD,QAAO,EACL,mBArBwB,aACvB,YAA2B;EAC1B,MAAM,oBAAoB,YAAY,
|
|
1
|
+
{"version":3,"file":"useToAddressReset.js","names":[],"sources":["../../../src/hooks/useToAddressReset.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useCallback } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'\nimport { useBookmarks } from '../stores/bookmarks/useBookmarks.js'\nimport { useFieldActions } from '../stores/form/useFieldActions.js'\nimport { RequiredUI } from '../types/widget.js'\n\nexport const useToAddressReset = (): {\n tryResetToAddress: (toChain: ExtendedChain) => void\n} => {\n const { requiredUI } = useWidgetConfig()\n const { setFieldValue } = useFieldActions()\n const { selectedBookmark } = useBookmarks()\n const { setSelectedBookmark } = useBookmarkActions()\n\n const tryResetToAddress = useCallback(\n (toChain: ExtendedChain) => {\n const requiredToAddress = requiredUI?.includes(RequiredUI.ToAddress)\n\n const bookmarkSatisfiesToChainType =\n selectedBookmark?.chainType === toChain?.chainType\n\n const shouldResetToAddress =\n !requiredToAddress && !bookmarkSatisfiesToChainType\n\n // We reset toAddress on each chain change if it's no longer required, ensuring that\n // switching chain types doesn't leave a stale toAddress from a different ecosystem.\n if (shouldResetToAddress) {\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n },\n [setFieldValue, setSelectedBookmark, requiredUI, selectedBookmark]\n )\n\n return {\n tryResetToAddress,\n }\n}\n"],"mappings":";;;;;;;AAQA,MAAa,0BAER;CACH,MAAM,EAAE,eAAe,iBAAiB;CACxC,MAAM,EAAE,kBAAkB,iBAAiB;CAC3C,MAAM,EAAE,qBAAqB,cAAc;CAC3C,MAAM,EAAE,wBAAwB,oBAAoB;AAsBpD,QAAO,EACL,mBArBwB,aACvB,YAA2B;EAC1B,MAAM,oBAAoB,YAAY,SAAA,YAA8B;EAEpE,MAAM,+BACJ,kBAAkB,cAAc,SAAS;AAO3C,MAJE,CAAC,qBAAqB,CAAC,8BAIC;AACxB,iBAAc,aAAa,IAAI,EAAE,WAAW,MAAM,CAAC;AACnD,wBAAqB;;IAGzB;EAAC;EAAe;EAAqB;EAAY;EAAiB,CAIjD,EAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenBalance.js","names":[],"sources":["../../../src/hooks/useTokenBalance.ts"],"sourcesContent":["import {\n getTokenBalances,\n type SDKClient,\n type Token,\n type TokenAmount,\n} from '@lifi/sdk'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nconst defaultRefetchInterval = 30_000\n\nexport const useTokenBalance = (\n accountAddress?: string,\n token?: Token\n): {\n token: TokenAmount | undefined\n isLoading: boolean\n refetch: () => void\n refetchNewBalance: () => void\n getTokenBalancesWithRetry: typeof getTokenBalancesWithRetry\n} => {\n const queryClient = useQueryClient()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const tokenBalanceQueryKey = useMemo(\n () =>\n [\n getQueryKey('token-balance', keyPrefix),\n accountAddress,\n token?.chainId,\n token?.address,\n ] as const,\n [token?.address, token?.chainId, accountAddress, keyPrefix]\n )\n\n const { data, isLoading, refetch } = useQuery({\n queryKey: tokenBalanceQueryKey,\n queryFn: async ({\n queryKey: [, accountAddress, tokenChainId, tokenAddress],\n }) => {\n const tokenBalances = await getTokenBalancesWithRetry(\n sdkClient,\n accountAddress as string,\n [token!]\n )\n\n if (!tokenBalances?.length) {\n throw new Error('Could not get tokens balance.')\n }\n\n const cachedTokenAmount =\n queryClient.getQueryData<TokenAmount>(tokenBalanceQueryKey)\n\n const tokenAmount = tokenBalances[0].amount\n\n if (cachedTokenAmount?.amount !== tokenAmount) {\n queryClient.setQueryDefaults(tokenBalanceQueryKey, {\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n })\n }\n\n queryClient.setQueriesData<TokenAmount[]>(\n {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n accountAddress,\n tokenChainId,\n ],\n },\n (data) => {\n if (data) {\n const clonedData = [...data]\n const index = clonedData.findIndex(\n (dataToken) => dataToken.address === tokenAddress\n )\n clonedData[index] = {\n ...clonedData[index],\n amount: tokenAmount,\n }\n return clonedData\n }\n }\n )\n\n return {\n ...tokenBalances[0],\n amount: tokenAmount,\n } as TokenAmount\n },\n\n enabled: Boolean(accountAddress && token),\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n })\n\n const refetchNewBalance = useCallback(() => {\n queryClient.setQueryDefaults(tokenBalanceQueryKey, {\n refetchInterval: 250,\n staleTime: 250,\n })\n }, [queryClient, tokenBalanceQueryKey])\n\n return {\n token: data,\n isLoading,\n refetch,\n refetchNewBalance,\n getTokenBalancesWithRetry,\n }\n}\n\nexport const getTokenBalancesWithRetry = async (\n sdkClient: SDKClient,\n accountAddress: string,\n tokens: Token[],\n depth = 0\n): Promise<TokenAmount[] | undefined> => {\n try {\n const tokenBalances = await getTokenBalances(\n sdkClient,\n accountAddress as string,\n tokens\n )\n if (!tokenBalances.every((token) => token.blockNumber)) {\n if (depth > 10) {\n console.warn('Token balance backoff depth exceeded.')\n return undefined\n }\n await new Promise((resolve) => {\n setTimeout(resolve, 1.5 ** depth * 100)\n })\n return getTokenBalancesWithRetry(\n sdkClient,\n accountAddress,\n tokens,\n depth + 1\n )\n }\n return tokenBalances\n } catch (_error) {\n console.warn(_error)\n }\n}\n"],"mappings":";;;;;;;AAYA,MAAM,yBAAyB;AAE/B,MAAa,mBACX,gBACA,UAOG;CACH,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAEhC,MAAM,uBAAuB,cAEzB;EACE,YAAY,iBAAiB,UAAU;EACvC;EACA,OAAO;EACP,OAAO;EACR,EACH;EAAC,OAAO;EAAS,OAAO;EAAS;EAAgB;EAAU,CAC5D;CAED,MAAM,EAAE,MAAM,WAAW,YAAY,SAAS;EAC5C,UAAU;EACV,SAAS,OAAO,EACd,UAAU,GAAG,gBAAgB,cAAc,oBACvC;GACJ,MAAM,gBAAgB,MAAM,0BAC1B,WACA,gBACA,CAAC,MAAO,CACT;AAED,OAAI,CAAC,eAAe,OAClB,OAAM,IAAI,MAAM,gCAAgC;GAGlD,MAAM,oBACJ,YAAY,aAA0B,qBAAqB;GAE7D,MAAM,cAAc,cAAc,GAAG;AAErC,OAAI,mBAAmB,WAAW,YAChC,aAAY,iBAAiB,sBAAsB;IACjD,iBAAiB;IACjB,WAAW;IACZ,CAAC;AAGJ,eAAY,eACV,EACE,UAAU;IACR,YAAY,kBAAkB,UAAU;IACxC;IACA;IACD,EACF,GACA,SAAS;AACR,QAAI,MAAM;KACR,MAAM,aAAa,CAAC,GAAG,KAAK;KAC5B,MAAM,QAAQ,WAAW,WACtB,cAAc,UAAU,YAAY,aACtC;AACD,gBAAW,SAAS;MAClB,GAAG,WAAW;MACd,QAAQ;MACT;AACD,YAAO;;KAGZ;AAED,UAAO;IACL,GAAG,cAAc;IACjB,QAAQ;IACT;;EAGH,SAAS,QAAQ,kBAAkB,MAAM;EACzC,iBAAiB;EACjB,WAAW;EACZ,CAAC;AASF,QAAO;EACL,OAAO;EACP;EACA;EACA,mBAXwB,kBAAkB;AAC1C,eAAY,iBAAiB,sBAAsB;IACjD,iBAAiB;IACjB,WAAW;IACZ,CAAC;KACD,CAAC,aAAa,qBAAqB,
|
|
1
|
+
{"version":3,"file":"useTokenBalance.js","names":[],"sources":["../../../src/hooks/useTokenBalance.ts"],"sourcesContent":["import {\n getTokenBalances,\n type SDKClient,\n type Token,\n type TokenAmount,\n} from '@lifi/sdk'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nconst defaultRefetchInterval = 30_000\n\nexport const useTokenBalance = (\n accountAddress?: string,\n token?: Token\n): {\n token: TokenAmount | undefined\n isLoading: boolean\n refetch: () => void\n refetchNewBalance: () => void\n getTokenBalancesWithRetry: typeof getTokenBalancesWithRetry\n} => {\n const queryClient = useQueryClient()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const tokenBalanceQueryKey = useMemo(\n () =>\n [\n getQueryKey('token-balance', keyPrefix),\n accountAddress,\n token?.chainId,\n token?.address,\n ] as const,\n [token?.address, token?.chainId, accountAddress, keyPrefix]\n )\n\n const { data, isLoading, refetch } = useQuery({\n queryKey: tokenBalanceQueryKey,\n queryFn: async ({\n queryKey: [, accountAddress, tokenChainId, tokenAddress],\n }) => {\n const tokenBalances = await getTokenBalancesWithRetry(\n sdkClient,\n accountAddress as string,\n [token!]\n )\n\n if (!tokenBalances?.length) {\n throw new Error('Could not get tokens balance.')\n }\n\n const cachedTokenAmount =\n queryClient.getQueryData<TokenAmount>(tokenBalanceQueryKey)\n\n const tokenAmount = tokenBalances[0].amount\n\n if (cachedTokenAmount?.amount !== tokenAmount) {\n queryClient.setQueryDefaults(tokenBalanceQueryKey, {\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n })\n }\n\n queryClient.setQueriesData<TokenAmount[]>(\n {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n accountAddress,\n tokenChainId,\n ],\n },\n (data) => {\n if (data) {\n const clonedData = [...data]\n const index = clonedData.findIndex(\n (dataToken) => dataToken.address === tokenAddress\n )\n clonedData[index] = {\n ...clonedData[index],\n amount: tokenAmount,\n }\n return clonedData\n }\n }\n )\n\n return {\n ...tokenBalances[0],\n amount: tokenAmount,\n } as TokenAmount\n },\n\n enabled: Boolean(accountAddress && token),\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n })\n\n const refetchNewBalance = useCallback(() => {\n queryClient.setQueryDefaults(tokenBalanceQueryKey, {\n refetchInterval: 250,\n staleTime: 250,\n })\n }, [queryClient, tokenBalanceQueryKey])\n\n return {\n token: data,\n isLoading,\n refetch,\n refetchNewBalance,\n getTokenBalancesWithRetry,\n }\n}\n\nexport const getTokenBalancesWithRetry = async (\n sdkClient: SDKClient,\n accountAddress: string,\n tokens: Token[],\n depth = 0\n): Promise<TokenAmount[] | undefined> => {\n try {\n const tokenBalances = await getTokenBalances(\n sdkClient,\n accountAddress as string,\n tokens\n )\n if (!tokenBalances.every((token) => token.blockNumber)) {\n if (depth > 10) {\n console.warn('Token balance backoff depth exceeded.')\n return undefined\n }\n await new Promise((resolve) => {\n setTimeout(resolve, 1.5 ** depth * 100)\n })\n return getTokenBalancesWithRetry(\n sdkClient,\n accountAddress,\n tokens,\n depth + 1\n )\n }\n return tokenBalances\n } catch (_error) {\n console.warn(_error)\n }\n}\n"],"mappings":";;;;;;;AAYA,MAAM,yBAAyB;AAE/B,MAAa,mBACX,gBACA,UAOG;CACH,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAEhC,MAAM,uBAAuB,cAEzB;EACE,YAAY,iBAAiB,UAAU;EACvC;EACA,OAAO;EACP,OAAO;EACR,EACH;EAAC,OAAO;EAAS,OAAO;EAAS;EAAgB;EAAU,CAC5D;CAED,MAAM,EAAE,MAAM,WAAW,YAAY,SAAS;EAC5C,UAAU;EACV,SAAS,OAAO,EACd,UAAU,GAAG,gBAAgB,cAAc,oBACvC;GACJ,MAAM,gBAAgB,MAAM,0BAC1B,WACA,gBACA,CAAC,MAAO,CACT;AAED,OAAI,CAAC,eAAe,OAClB,OAAM,IAAI,MAAM,gCAAgC;GAGlD,MAAM,oBACJ,YAAY,aAA0B,qBAAqB;GAE7D,MAAM,cAAc,cAAc,GAAG;AAErC,OAAI,mBAAmB,WAAW,YAChC,aAAY,iBAAiB,sBAAsB;IACjD,iBAAiB;IACjB,WAAW;IACZ,CAAC;AAGJ,eAAY,eACV,EACE,UAAU;IACR,YAAY,kBAAkB,UAAU;IACxC;IACA;IACD,EACF,GACA,SAAS;AACR,QAAI,MAAM;KACR,MAAM,aAAa,CAAC,GAAG,KAAK;KAC5B,MAAM,QAAQ,WAAW,WACtB,cAAc,UAAU,YAAY,aACtC;AACD,gBAAW,SAAS;MAClB,GAAG,WAAW;MACd,QAAQ;MACT;AACD,YAAO;;KAGZ;AAED,UAAO;IACL,GAAG,cAAc;IACjB,QAAQ;IACT;;EAGH,SAAS,QAAQ,kBAAkB,MAAM;EACzC,iBAAiB;EACjB,WAAW;EACZ,CAAC;AASF,QAAO;EACL,OAAO;EACP;EACA;EACA,mBAXwB,kBAAkB;AAC1C,eAAY,iBAAiB,sBAAsB;IACjD,iBAAiB;IACjB,WAAW;IACZ,CAAC;KACD,CAAC,aAAa,qBAAqB,CAMnB;EACjB;EACD;;AAGH,MAAa,4BAA4B,OACvC,WACA,gBACA,QACA,QAAQ,MAC+B;AACvC,KAAI;EACF,MAAM,gBAAgB,MAAM,iBAC1B,WACA,gBACA,OACD;AACD,MAAI,CAAC,cAAc,OAAO,UAAU,MAAM,YAAY,EAAE;AACtD,OAAI,QAAQ,IAAI;AACd,YAAQ,KAAK,wCAAwC;AACrD;;AAEF,SAAM,IAAI,SAAS,YAAY;AAC7B,eAAW,SAAS,OAAO,QAAQ,IAAI;KACvC;AACF,UAAO,0BACL,WACA,gBACA,QACA,QAAQ,EACT;;AAEH,SAAO;UACA,QAAQ;AACf,UAAQ,KAAK,OAAO"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
-
import
|
|
2
|
+
import "../types/widget.js";
|
|
3
3
|
import { formatTokenPrice } from "../utils/format.js";
|
|
4
4
|
import { useSettings } from "../stores/settings/useSettings.js";
|
|
5
5
|
import { useTokens } from "./useTokens.js";
|
|
@@ -58,7 +58,7 @@ const useTokenBalances = (selectedChainId, formType, isAllNetworks, search) => {
|
|
|
58
58
|
const displayedTokensWithBalances = useMemo(() => {
|
|
59
59
|
const balancesByChain = isAllNetworks ? allTokensWithBalances : selectedChainId ? allTokensWithBalances?.filter((t) => t.chainId === selectedChainId) : void 0;
|
|
60
60
|
const displayedTokensSet = new Set(displayedTokensList?.map((t) => `${t.chainId}-${t.address.toLowerCase()}`) || []);
|
|
61
|
-
const hideSmallBalances = !!smallBalanceThreshold && !hiddenUI?.includes(
|
|
61
|
+
const hideSmallBalances = !!smallBalanceThreshold && !hiddenUI?.includes("hideSmallBalances");
|
|
62
62
|
const threshold = hideSmallBalances ? Number.parseFloat(smallBalanceThreshold) : void 0;
|
|
63
63
|
if (!balancesByChain) return;
|
|
64
64
|
return balancesByChain.reduce((acc, token) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenBalances.js","names":[],"sources":["../../../src/hooks/useTokenBalances.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { usePinnedTokensStore } from '../stores/pinnedTokens/PinnedTokensStore.js'\nimport { useSettings } from '../stores/settings/useSettings.js'\nimport type { TokenAmount } from '../types/token.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { formatTokenPrice } from '../utils/format.js'\nimport { isSearchMatch, processTokenBalances } from '../utils/tokenList.js'\nimport { useAccountsBalancesData } from './useAccountsBalancesData.js'\nimport { useTokenBalancesQueries } from './useTokenBalancesQueries.js'\nimport { useTokens } from './useTokens.js'\n\nexport const useTokenBalances = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n search?: string\n): {\n tokens: TokenAmount[]\n withCategories: boolean\n withPinnedTokens: boolean\n isTokensLoading: boolean\n isSearchLoading: boolean\n isBalanceLoading: boolean\n} => {\n const { hiddenUI } = useWidgetConfig()\n const {\n allTokens,\n isLoading: isTokensLoading,\n isSearchLoading,\n } = useTokens(formType, search, isAllNetworks ? undefined : selectedChainId)\n\n const { data: accountsWithAllTokens, isLoading: isAccountsLoading } =\n useAccountsBalancesData(selectedChainId, formType, isAllNetworks, allTokens)\n\n const isBalanceLoadingEnabled =\n Boolean(accountsWithAllTokens) && !isAccountsLoading\n\n const { data: allTokensWithBalances, isLoading: isBalanceQueriesLoading } =\n useTokenBalancesQueries(accountsWithAllTokens, isBalanceLoadingEnabled)\n\n const { tokens: configTokens } = useWidgetConfig()\n const { smallBalanceThreshold } = useSettings(['smallBalanceThreshold'])\n\n const pinnedTokens = usePinnedTokensStore((state) => state.pinnedTokens)\n\n const isBalanceLoading =\n (isBalanceQueriesLoading || isAccountsLoading) &&\n !allTokensWithBalances?.length\n\n // Create function to check if token is pinned\n const isPinnedToken = useMemo(() => {\n if (isAllNetworks) {\n // For all networks, check all pinned tokens\n const allPinned: Array<{ chainId: number; tokenAddress: string }> = []\n Object.entries(pinnedTokens).forEach(([chainIdStr, addresses]) => {\n const chainId = Number.parseInt(chainIdStr, 10)\n addresses.forEach((address) => {\n allPinned.push({ chainId, tokenAddress: address })\n })\n })\n const pinnedSet = new Set(\n allPinned.map((p) => `${p.chainId}-${p.tokenAddress.toLowerCase()}`)\n )\n return (chainId: number, tokenAddress: string) => {\n const key = `${chainId}-${tokenAddress.toLowerCase()}`\n return pinnedSet.has(key)\n }\n } else if (selectedChainId) {\n // For single chain, check only selected chain\n const chainPinnedTokens = pinnedTokens[selectedChainId] || []\n const pinnedSet = new Set(\n chainPinnedTokens.map((addr) => addr.toLowerCase())\n )\n return (chainId: number, tokenAddress: string) => {\n return (\n chainId === selectedChainId &&\n pinnedSet.has(tokenAddress.toLowerCase())\n )\n }\n }\n return undefined\n }, [isAllNetworks, selectedChainId, pinnedTokens])\n\n const displayedTokensList = useMemo(() => {\n const tokensByChain = isAllNetworks\n ? Object.values(allTokens ?? {}).flat()\n : selectedChainId\n ? allTokens?.[selectedChainId]\n : undefined\n return tokensByChain?.filter((t) => isSearchMatch(t, search)) ?? []\n }, [allTokens, isAllNetworks, selectedChainId, search])\n\n const displayedTokensWithBalances = useMemo(() => {\n const balancesByChain = isAllNetworks\n ? allTokensWithBalances\n : selectedChainId\n ? allTokensWithBalances?.filter((t) => t.chainId === selectedChainId)\n : undefined\n const displayedTokensSet = new Set(\n displayedTokensList?.map(\n (t) => `${t.chainId}-${t.address.toLowerCase()}`\n ) || []\n )\n\n const hideSmallBalances =\n !!smallBalanceThreshold && !hiddenUI?.includes(HiddenUI.HideSmallBalances)\n const threshold = hideSmallBalances\n ? Number.parseFloat(smallBalanceThreshold)\n : undefined\n\n if (!balancesByChain) {\n return undefined\n }\n\n return balancesByChain.reduce<typeof balancesByChain>((acc, token) => {\n const tokenKey = `${token.chainId}-${token.address.toLowerCase()}`\n // Check if token is in displayed list and has amount\n const isInDisplayedList = displayedTokensSet.has(tokenKey) && token.amount\n // Check if it matches search (for cached appended tokens)\n const matchesSearch = isSearchMatch(token, search)\n\n // Filter: only include tokens that match our criteria\n if (!isInDisplayedList && !matchesSearch) {\n return acc\n }\n\n // Apply small balance threshold transformation if enabled\n let processedToken = token\n if (\n hideSmallBalances &&\n threshold !== undefined &&\n threshold >= 0 &&\n token.amount\n ) {\n const balanceUSD = formatTokenPrice(\n token.amount,\n token.priceUSD,\n token.decimals\n )\n if (balanceUSD < threshold) {\n processedToken = {\n ...token,\n amount: 0n,\n }\n }\n }\n\n acc.push(processedToken)\n return acc\n }, [])\n }, [\n allTokensWithBalances,\n displayedTokensList,\n search,\n selectedChainId,\n isAllNetworks,\n smallBalanceThreshold,\n hiddenUI,\n ])\n\n const { processedTokens, withCategories, withPinnedTokens } = useMemo(() => {\n return processTokenBalances(\n isBalanceLoading,\n isAllNetworks || !!search,\n configTokens,\n selectedChainId,\n displayedTokensList,\n displayedTokensWithBalances,\n isPinnedToken\n )\n }, [\n isBalanceLoading,\n isAllNetworks,\n configTokens,\n selectedChainId,\n displayedTokensList,\n displayedTokensWithBalances,\n search,\n isPinnedToken,\n ])\n\n return {\n tokens: processedTokens ?? [],\n withCategories,\n withPinnedTokens,\n isTokensLoading,\n isSearchLoading,\n isBalanceLoading,\n }\n}\n"],"mappings":";;;;;;;;;;;AAaA,MAAa,oBACX,iBACA,UACA,eACA,WAQG;CACH,MAAM,EAAE,aAAa,iBAAiB;CACtC,MAAM,EACJ,WACA,WAAW,iBACX,oBACE,UAAU,UAAU,QAAQ,gBAAgB,KAAA,IAAY,gBAAgB;CAE5E,MAAM,EAAE,MAAM,uBAAuB,WAAW,sBAC9C,wBAAwB,iBAAiB,UAAU,eAAe,UAAU;CAK9E,MAAM,EAAE,MAAM,uBAAuB,WAAW,4BAC9C,wBAAwB,uBAHxB,QAAQ,sBAAsB,IAAI,CAAC,kBAGoC;CAEzE,MAAM,EAAE,QAAQ,iBAAiB,iBAAiB;CAClD,MAAM,EAAE,0BAA0B,YAAY,CAAC,wBAAwB,CAAC;CAExE,MAAM,eAAe,sBAAsB,UAAU,MAAM,aAAa;CAExE,MAAM,oBACH,2BAA2B,sBAC5B,CAAC,uBAAuB;CAG1B,MAAM,gBAAgB,cAAc;AAClC,MAAI,eAAe;GAEjB,MAAM,YAA8D,EAAE;AACtE,UAAO,QAAQ,aAAa,CAAC,SAAS,CAAC,YAAY,eAAe;IAChE,MAAM,UAAU,OAAO,SAAS,YAAY,GAAG;AAC/C,cAAU,SAAS,YAAY;AAC7B,eAAU,KAAK;MAAE;MAAS,cAAc;MAAS,CAAC;MAClD;KACF;GACF,MAAM,YAAY,IAAI,IACpB,UAAU,KAAK,MAAM,GAAG,EAAE,QAAQ,GAAG,EAAE,aAAa,aAAa,GAAG,CACrE;AACD,WAAQ,SAAiB,iBAAyB;IAChD,MAAM,MAAM,GAAG,QAAQ,GAAG,aAAa,aAAa;AACpD,WAAO,UAAU,IAAI,IAAI;;aAElB,iBAAiB;GAE1B,MAAM,oBAAoB,aAAa,oBAAoB,EAAE;GAC7D,MAAM,YAAY,IAAI,IACpB,kBAAkB,KAAK,SAAS,KAAK,aAAa,CAAC,CACpD;AACD,WAAQ,SAAiB,iBAAyB;AAChD,WACE,YAAY,mBACZ,UAAU,IAAI,aAAa,aAAa,CAAC;;;IAK9C;EAAC;EAAe;EAAiB;EAAa,CAAC;CAElD,MAAM,sBAAsB,cAAc;AAMxC,UALsB,gBAClB,OAAO,OAAO,aAAa,EAAE,CAAC,CAAC,MAAM,GACrC,kBACE,YAAY,mBACZ,KAAA,IACgB,QAAQ,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE;IAClE;EAAC;EAAW;EAAe;EAAiB;EAAO,CAAC;CAEvD,MAAM,8BAA8B,cAAc;EAChD,MAAM,kBAAkB,gBACpB,wBACA,kBACE,uBAAuB,QAAQ,MAAM,EAAE,YAAY,gBAAgB,GACnE,KAAA;EACN,MAAM,qBAAqB,IAAI,IAC7B,qBAAqB,KAClB,MAAM,GAAG,EAAE,QAAQ,GAAG,EAAE,QAAQ,aAAa,GAC/C,IAAI,EAAE,CACR;EAED,MAAM,oBACJ,CAAC,CAAC,yBAAyB,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"useTokenBalances.js","names":[],"sources":["../../../src/hooks/useTokenBalances.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { usePinnedTokensStore } from '../stores/pinnedTokens/PinnedTokensStore.js'\nimport { useSettings } from '../stores/settings/useSettings.js'\nimport type { TokenAmount } from '../types/token.js'\nimport { HiddenUI } from '../types/widget.js'\nimport { formatTokenPrice } from '../utils/format.js'\nimport { isSearchMatch, processTokenBalances } from '../utils/tokenList.js'\nimport { useAccountsBalancesData } from './useAccountsBalancesData.js'\nimport { useTokenBalancesQueries } from './useTokenBalancesQueries.js'\nimport { useTokens } from './useTokens.js'\n\nexport const useTokenBalances = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n search?: string\n): {\n tokens: TokenAmount[]\n withCategories: boolean\n withPinnedTokens: boolean\n isTokensLoading: boolean\n isSearchLoading: boolean\n isBalanceLoading: boolean\n} => {\n const { hiddenUI } = useWidgetConfig()\n const {\n allTokens,\n isLoading: isTokensLoading,\n isSearchLoading,\n } = useTokens(formType, search, isAllNetworks ? undefined : selectedChainId)\n\n const { data: accountsWithAllTokens, isLoading: isAccountsLoading } =\n useAccountsBalancesData(selectedChainId, formType, isAllNetworks, allTokens)\n\n const isBalanceLoadingEnabled =\n Boolean(accountsWithAllTokens) && !isAccountsLoading\n\n const { data: allTokensWithBalances, isLoading: isBalanceQueriesLoading } =\n useTokenBalancesQueries(accountsWithAllTokens, isBalanceLoadingEnabled)\n\n const { tokens: configTokens } = useWidgetConfig()\n const { smallBalanceThreshold } = useSettings(['smallBalanceThreshold'])\n\n const pinnedTokens = usePinnedTokensStore((state) => state.pinnedTokens)\n\n const isBalanceLoading =\n (isBalanceQueriesLoading || isAccountsLoading) &&\n !allTokensWithBalances?.length\n\n // Create function to check if token is pinned\n const isPinnedToken = useMemo(() => {\n if (isAllNetworks) {\n // For all networks, check all pinned tokens\n const allPinned: Array<{ chainId: number; tokenAddress: string }> = []\n Object.entries(pinnedTokens).forEach(([chainIdStr, addresses]) => {\n const chainId = Number.parseInt(chainIdStr, 10)\n addresses.forEach((address) => {\n allPinned.push({ chainId, tokenAddress: address })\n })\n })\n const pinnedSet = new Set(\n allPinned.map((p) => `${p.chainId}-${p.tokenAddress.toLowerCase()}`)\n )\n return (chainId: number, tokenAddress: string) => {\n const key = `${chainId}-${tokenAddress.toLowerCase()}`\n return pinnedSet.has(key)\n }\n } else if (selectedChainId) {\n // For single chain, check only selected chain\n const chainPinnedTokens = pinnedTokens[selectedChainId] || []\n const pinnedSet = new Set(\n chainPinnedTokens.map((addr) => addr.toLowerCase())\n )\n return (chainId: number, tokenAddress: string) => {\n return (\n chainId === selectedChainId &&\n pinnedSet.has(tokenAddress.toLowerCase())\n )\n }\n }\n return undefined\n }, [isAllNetworks, selectedChainId, pinnedTokens])\n\n const displayedTokensList = useMemo(() => {\n const tokensByChain = isAllNetworks\n ? Object.values(allTokens ?? {}).flat()\n : selectedChainId\n ? allTokens?.[selectedChainId]\n : undefined\n return tokensByChain?.filter((t) => isSearchMatch(t, search)) ?? []\n }, [allTokens, isAllNetworks, selectedChainId, search])\n\n const displayedTokensWithBalances = useMemo(() => {\n const balancesByChain = isAllNetworks\n ? allTokensWithBalances\n : selectedChainId\n ? allTokensWithBalances?.filter((t) => t.chainId === selectedChainId)\n : undefined\n const displayedTokensSet = new Set(\n displayedTokensList?.map(\n (t) => `${t.chainId}-${t.address.toLowerCase()}`\n ) || []\n )\n\n const hideSmallBalances =\n !!smallBalanceThreshold && !hiddenUI?.includes(HiddenUI.HideSmallBalances)\n const threshold = hideSmallBalances\n ? Number.parseFloat(smallBalanceThreshold)\n : undefined\n\n if (!balancesByChain) {\n return undefined\n }\n\n return balancesByChain.reduce<typeof balancesByChain>((acc, token) => {\n const tokenKey = `${token.chainId}-${token.address.toLowerCase()}`\n // Check if token is in displayed list and has amount\n const isInDisplayedList = displayedTokensSet.has(tokenKey) && token.amount\n // Check if it matches search (for cached appended tokens)\n const matchesSearch = isSearchMatch(token, search)\n\n // Filter: only include tokens that match our criteria\n if (!isInDisplayedList && !matchesSearch) {\n return acc\n }\n\n // Apply small balance threshold transformation if enabled\n let processedToken = token\n if (\n hideSmallBalances &&\n threshold !== undefined &&\n threshold >= 0 &&\n token.amount\n ) {\n const balanceUSD = formatTokenPrice(\n token.amount,\n token.priceUSD,\n token.decimals\n )\n if (balanceUSD < threshold) {\n processedToken = {\n ...token,\n amount: 0n,\n }\n }\n }\n\n acc.push(processedToken)\n return acc\n }, [])\n }, [\n allTokensWithBalances,\n displayedTokensList,\n search,\n selectedChainId,\n isAllNetworks,\n smallBalanceThreshold,\n hiddenUI,\n ])\n\n const { processedTokens, withCategories, withPinnedTokens } = useMemo(() => {\n return processTokenBalances(\n isBalanceLoading,\n isAllNetworks || !!search,\n configTokens,\n selectedChainId,\n displayedTokensList,\n displayedTokensWithBalances,\n isPinnedToken\n )\n }, [\n isBalanceLoading,\n isAllNetworks,\n configTokens,\n selectedChainId,\n displayedTokensList,\n displayedTokensWithBalances,\n search,\n isPinnedToken,\n ])\n\n return {\n tokens: processedTokens ?? [],\n withCategories,\n withPinnedTokens,\n isTokensLoading,\n isSearchLoading,\n isBalanceLoading,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenBalancesQueries.js","names":[],"sources":["../../../src/hooks/useTokenBalancesQueries.ts"],"sourcesContent":["import { getTokenBalances, type TokenExtended } from '@lifi/sdk'\nimport { useQueries } from '@tanstack/react-query'\nimport { useMemo, useRef } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { TokenAmount, TokenAmountExtended } from '../types/token.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nconst defaultRefetchInterval = 32_000\n\nexport const useTokenBalancesQueries = (\n accountsWithTokens?: Record<string, Record<number, TokenExtended[]>>,\n isBalanceLoadingEnabled?: boolean\n): {\n data: TokenAmount[] | undefined\n isLoading: boolean\n isError: boolean\n} => {\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const firstLoadStartRef = useRef<number | null>(null)\n\n const queryConfig = useMemo(() => {\n if (!accountsWithTokens) {\n return []\n }\n return Object.entries(accountsWithTokens).flatMap(\n ([accountAddress, chainTokens]) =>\n Object.entries(chainTokens).map(([chainIdStr, tokens]) => {\n const chainId = Number(chainIdStr)\n return {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n accountAddress,\n chainId,\n tokens.length,\n ],\n queryFn: async (): Promise<TokenAmountExtended[]> => {\n if (!accountAddress || !tokens) {\n return []\n }\n return await getTokenBalances(sdkClient, accountAddress, tokens)\n },\n enabled: isBalanceLoadingEnabled,\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n keepPreviousData: true,\n }\n })\n )\n }, [accountsWithTokens, isBalanceLoadingEnabled, keyPrefix, sdkClient])\n\n const result = useQueries({\n queries: queryConfig,\n combine: (results) => {\n const now = Date.now()\n\n const hasLoadingQueries = results.some((result) => result.isLoading)\n if (hasLoadingQueries && firstLoadStartRef.current === null) {\n firstLoadStartRef.current = now\n }\n\n const allComplete = results.every(\n (result) => result.isSuccess || result.isError\n )\n\n // Reset the start time when all queries complete\n if (allComplete) {\n firstLoadStartRef.current = null\n }\n\n // Calculate time since first load started\n const timeSinceStart = firstLoadStartRef.current\n ? now - firstLoadStartRef.current\n : 0\n\n // Return results if all complete OR if 500ms have passed since first query started\n const shouldReturnResults = allComplete || timeSinceStart >= 500\n\n if (shouldReturnResults) {\n const data: TokenAmount[] = results\n .flatMap((result) => result.data || [])\n .filter((token) => token.amount)\n return {\n data,\n isLoading: !allComplete,\n isError: results.some((result) => result.isError),\n }\n }\n\n return {\n data: undefined,\n isLoading: true,\n isError: false,\n }\n },\n })\n\n return result\n}\n"],"mappings":";;;;;;;AAQA,MAAM,yBAAyB;AAE/B,MAAa,2BACX,oBACA,4BAKG;CACH,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAChC,MAAM,oBAAoB,OAAsB,KAAK;AA8ErD,QA9Ce,WAAW;EACxB,SA/BkB,cAAc;AAChC,OAAI,CAAC,mBACH,QAAO,EAAE;AAEX,UAAO,OAAO,QAAQ,mBAAmB,CAAC,SACvC,CAAC,gBAAgB,iBAChB,OAAO,QAAQ,YAAY,CAAC,KAAK,CAAC,YAAY,YAAY;IACxD,MAAM,UAAU,OAAO,WAAW;AAClC,WAAO;KACL,UAAU;MACR,YAAY,kBAAkB,UAAU;MACxC;MACA;MACA,OAAO;MACR;KACD,SAAS,YAA4C;AACnD,UAAI,CAAC,kBAAkB,CAAC,OACtB,QAAO,EAAE;AAEX,aAAO,MAAM,iBAAiB,WAAW,gBAAgB,OAAO;;KAElE,SAAS;KACT,iBAAiB;KACjB,WAAW;KACX,kBAAkB;KACnB;KACD,CACL;KACA;GAAC;GAAoB;GAAyB;GAAW;GAAU,
|
|
1
|
+
{"version":3,"file":"useTokenBalancesQueries.js","names":[],"sources":["../../../src/hooks/useTokenBalancesQueries.ts"],"sourcesContent":["import { getTokenBalances, type TokenExtended } from '@lifi/sdk'\nimport { useQueries } from '@tanstack/react-query'\nimport { useMemo, useRef } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { TokenAmount, TokenAmountExtended } from '../types/token.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nconst defaultRefetchInterval = 32_000\n\nexport const useTokenBalancesQueries = (\n accountsWithTokens?: Record<string, Record<number, TokenExtended[]>>,\n isBalanceLoadingEnabled?: boolean\n): {\n data: TokenAmount[] | undefined\n isLoading: boolean\n isError: boolean\n} => {\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const firstLoadStartRef = useRef<number | null>(null)\n\n const queryConfig = useMemo(() => {\n if (!accountsWithTokens) {\n return []\n }\n return Object.entries(accountsWithTokens).flatMap(\n ([accountAddress, chainTokens]) =>\n Object.entries(chainTokens).map(([chainIdStr, tokens]) => {\n const chainId = Number(chainIdStr)\n return {\n queryKey: [\n getQueryKey('token-balances', keyPrefix),\n accountAddress,\n chainId,\n tokens.length,\n ],\n queryFn: async (): Promise<TokenAmountExtended[]> => {\n if (!accountAddress || !tokens) {\n return []\n }\n return await getTokenBalances(sdkClient, accountAddress, tokens)\n },\n enabled: isBalanceLoadingEnabled,\n refetchInterval: defaultRefetchInterval,\n staleTime: defaultRefetchInterval,\n keepPreviousData: true,\n }\n })\n )\n }, [accountsWithTokens, isBalanceLoadingEnabled, keyPrefix, sdkClient])\n\n const result = useQueries({\n queries: queryConfig,\n combine: (results) => {\n const now = Date.now()\n\n const hasLoadingQueries = results.some((result) => result.isLoading)\n if (hasLoadingQueries && firstLoadStartRef.current === null) {\n firstLoadStartRef.current = now\n }\n\n const allComplete = results.every(\n (result) => result.isSuccess || result.isError\n )\n\n // Reset the start time when all queries complete\n if (allComplete) {\n firstLoadStartRef.current = null\n }\n\n // Calculate time since first load started\n const timeSinceStart = firstLoadStartRef.current\n ? now - firstLoadStartRef.current\n : 0\n\n // Return results if all complete OR if 500ms have passed since first query started\n const shouldReturnResults = allComplete || timeSinceStart >= 500\n\n if (shouldReturnResults) {\n const data: TokenAmount[] = results\n .flatMap((result) => result.data || [])\n .filter((token) => token.amount)\n return {\n data,\n isLoading: !allComplete,\n isError: results.some((result) => result.isError),\n }\n }\n\n return {\n data: undefined,\n isLoading: true,\n isError: false,\n }\n },\n })\n\n return result\n}\n"],"mappings":";;;;;;;AAQA,MAAM,yBAAyB;AAE/B,MAAa,2BACX,oBACA,4BAKG;CACH,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAChC,MAAM,oBAAoB,OAAsB,KAAK;AA8ErD,QA9Ce,WAAW;EACxB,SA/BkB,cAAc;AAChC,OAAI,CAAC,mBACH,QAAO,EAAE;AAEX,UAAO,OAAO,QAAQ,mBAAmB,CAAC,SACvC,CAAC,gBAAgB,iBAChB,OAAO,QAAQ,YAAY,CAAC,KAAK,CAAC,YAAY,YAAY;IACxD,MAAM,UAAU,OAAO,WAAW;AAClC,WAAO;KACL,UAAU;MACR,YAAY,kBAAkB,UAAU;MACxC;MACA;MACA,OAAO;MACR;KACD,SAAS,YAA4C;AACnD,UAAI,CAAC,kBAAkB,CAAC,OACtB,QAAO,EAAE;AAEX,aAAO,MAAM,iBAAiB,WAAW,gBAAgB,OAAO;;KAElE,SAAS;KACT,iBAAiB;KACjB,WAAW;KACX,kBAAkB;KACnB;KACD,CACL;KACA;GAAC;GAAoB;GAAyB;GAAW;GAAU,CAGhD;EACpB,UAAU,YAAY;GACpB,MAAM,MAAM,KAAK,KAAK;AAGtB,OAD0B,QAAQ,MAAM,WAAW,OAAO,UACrC,IAAI,kBAAkB,YAAY,KACrD,mBAAkB,UAAU;GAG9B,MAAM,cAAc,QAAQ,OACzB,WAAW,OAAO,aAAa,OAAO,QACxC;AAGD,OAAI,YACF,mBAAkB,UAAU;GAI9B,MAAM,iBAAiB,kBAAkB,UACrC,MAAM,kBAAkB,UACxB;AAKJ,OAF4B,eAAe,kBAAkB,IAM3D,QAAO;IACL,MAJ0B,QACzB,SAAS,WAAW,OAAO,QAAQ,EAAE,CAAC,CACtC,QAAQ,UAAU,MAAM,OAErB;IACJ,WAAW,CAAC;IACZ,SAAS,QAAQ,MAAM,WAAW,OAAO,QAAQ;IAClD;AAGH,UAAO;IACL,MAAM,KAAA;IACN,WAAW;IACX,SAAS;IACV;;EAEJ,CAEY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenSearch.js","names":[],"sources":["../../../src/hooks/useTokenSearch.ts"],"sourcesContent":["import {\n type BaseToken,\n type ChainId,\n getToken,\n type TokenExtended,\n} from '@lifi/sdk'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nexport const useTokenSearch = (\n chainId?: number,\n tokenQuery?: string,\n enabled?: boolean,\n formType?: FormType\n): {\n token: TokenExtended | undefined\n isLoading: boolean\n} => {\n const queryClient = useQueryClient()\n const { tokens: configTokens, keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const { data, isLoading } = useQuery({\n queryKey: [getQueryKey('token-search', keyPrefix), chainId, tokenQuery],\n queryFn: async ({ queryKey: [, chainId, tokenQuery], signal }) => {\n const token = await getToken(\n sdkClient,\n chainId as ChainId,\n tokenQuery as string,\n {\n signal,\n }\n )\n\n if (token) {\n // Filter config tokens by chain before checking if token is allowed\n const filteredConfigTokens = getConfigItemSets(\n configTokens,\n (tokens: BaseToken[]) =>\n new Set(\n tokens\n .filter((t) => t.chainId === token.chainId)\n .map((t) => t.address.toLowerCase())\n ),\n formType\n )\n\n // Return undefined if the token is denied\n if (\n !isFormItemAllowed(token, filteredConfigTokens, formType, (t) =>\n t.address.toLowerCase()\n )\n ) {\n return null\n }\n\n // Add token to main tokens cache\n queryClient.setQueriesData<TokensByChain>(\n { queryKey: [getQueryKey('tokens', keyPrefix)] },\n (data) => {\n if (!data) {\n return data\n }\n const chainTokens = data[chainId as number]\n if (\n chainTokens?.some(\n (t) => t.address.toLowerCase() === token.address.toLowerCase()\n )\n ) {\n return data\n }\n // Mark token from search as unverified\n return {\n ...data,\n [chainId as number]: [\n ...(chainTokens ?? []),\n { ...token, verified: false },\n ],\n }\n }\n )\n }\n return token as TokenExtended\n },\n\n enabled: Boolean(chainId && tokenQuery && enabled),\n retry: false,\n })\n return {\n token: data || undefined,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;AAcA,MAAa,kBACX,SACA,YACA,SACA,aAIG;CACH,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,QAAQ,cAAc,cAAc,iBAAiB;CAC7D,MAAM,YAAY,cAAc;CAEhC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GAAC,YAAY,gBAAgB,UAAU;GAAE;GAAS;GAAW;EACvE,SAAS,OAAO,EAAE,UAAU,GAAG,SAAS,aAAa,aAAa;GAChE,MAAM,QAAQ,MAAM,SAClB,WACA,SACA,YACA,EACE,QACD,CACF;AAED,OAAI,OAAO;AAcT,QACE,CAAC,kBAAkB,OAbQ,kBAC3B,eACC,WACC,IAAI,IACF,OACG,QAAQ,MAAM,EAAE,YAAY,MAAM,QAAQ,CAC1C,KAAK,MAAM,EAAE,QAAQ,aAAa,CAAC,CACvC,EACH,
|
|
1
|
+
{"version":3,"file":"useTokenSearch.js","names":[],"sources":["../../../src/hooks/useTokenSearch.ts"],"sourcesContent":["import {\n type BaseToken,\n type ChainId,\n getToken,\n type TokenExtended,\n} from '@lifi/sdk'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nexport const useTokenSearch = (\n chainId?: number,\n tokenQuery?: string,\n enabled?: boolean,\n formType?: FormType\n): {\n token: TokenExtended | undefined\n isLoading: boolean\n} => {\n const queryClient = useQueryClient()\n const { tokens: configTokens, keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const { data, isLoading } = useQuery({\n queryKey: [getQueryKey('token-search', keyPrefix), chainId, tokenQuery],\n queryFn: async ({ queryKey: [, chainId, tokenQuery], signal }) => {\n const token = await getToken(\n sdkClient,\n chainId as ChainId,\n tokenQuery as string,\n {\n signal,\n }\n )\n\n if (token) {\n // Filter config tokens by chain before checking if token is allowed\n const filteredConfigTokens = getConfigItemSets(\n configTokens,\n (tokens: BaseToken[]) =>\n new Set(\n tokens\n .filter((t) => t.chainId === token.chainId)\n .map((t) => t.address.toLowerCase())\n ),\n formType\n )\n\n // Return undefined if the token is denied\n if (\n !isFormItemAllowed(token, filteredConfigTokens, formType, (t) =>\n t.address.toLowerCase()\n )\n ) {\n return null\n }\n\n // Add token to main tokens cache\n queryClient.setQueriesData<TokensByChain>(\n { queryKey: [getQueryKey('tokens', keyPrefix)] },\n (data) => {\n if (!data) {\n return data\n }\n const chainTokens = data[chainId as number]\n if (\n chainTokens?.some(\n (t) => t.address.toLowerCase() === token.address.toLowerCase()\n )\n ) {\n return data\n }\n // Mark token from search as unverified\n return {\n ...data,\n [chainId as number]: [\n ...(chainTokens ?? []),\n { ...token, verified: false },\n ],\n }\n }\n )\n }\n return token as TokenExtended\n },\n\n enabled: Boolean(chainId && tokenQuery && enabled),\n retry: false,\n })\n return {\n token: data || undefined,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;AAcA,MAAa,kBACX,SACA,YACA,SACA,aAIG;CACH,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,QAAQ,cAAc,cAAc,iBAAiB;CAC7D,MAAM,YAAY,cAAc;CAEhC,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU;GAAC,YAAY,gBAAgB,UAAU;GAAE;GAAS;GAAW;EACvE,SAAS,OAAO,EAAE,UAAU,GAAG,SAAS,aAAa,aAAa;GAChE,MAAM,QAAQ,MAAM,SAClB,WACA,SACA,YACA,EACE,QACD,CACF;AAED,OAAI,OAAO;AAcT,QACE,CAAC,kBAAkB,OAbQ,kBAC3B,eACC,WACC,IAAI,IACF,OACG,QAAQ,MAAM,EAAE,YAAY,MAAM,QAAQ,CAC1C,KAAK,MAAM,EAAE,QAAQ,aAAa,CAAC,CACvC,EACH,SAK8C,EAAE,WAAW,MACzD,EAAE,QAAQ,aAAa,CACxB,CAED,QAAO;AAIT,gBAAY,eACV,EAAE,UAAU,CAAC,YAAY,UAAU,UAAU,CAAC,EAAE,GAC/C,SAAS;AACR,SAAI,CAAC,KACH,QAAO;KAET,MAAM,cAAc,KAAK;AACzB,SACE,aAAa,MACV,MAAM,EAAE,QAAQ,aAAa,KAAK,MAAM,QAAQ,aAAa,CAC/D,CAED,QAAO;AAGT,YAAO;MACL,GAAG;OACF,UAAoB,CACnB,GAAI,eAAe,EAAE,EACrB;OAAE,GAAG;OAAO,UAAU;OAAO,CAC9B;MACF;MAEJ;;AAEH,UAAO;;EAGT,SAAS,QAAQ,WAAW,cAAc,QAAQ;EAClD,OAAO;EACR,CAAC;AACF,QAAO;EACL,OAAO,QAAQ,KAAA;EACf;EACD"}
|
|
@@ -22,7 +22,8 @@ const useTokens = (formType, search, chainId) => {
|
|
|
22
22
|
ChainType.EVM,
|
|
23
23
|
ChainType.SVM,
|
|
24
24
|
ChainType.UTXO,
|
|
25
|
-
ChainType.MVM
|
|
25
|
+
ChainType.MVM,
|
|
26
|
+
ChainType.TVM
|
|
26
27
|
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)),
|
|
27
28
|
orderBy: "volumeUSD24H",
|
|
28
29
|
extended: true,
|
|
@@ -50,7 +51,8 @@ const useTokens = (formType, search, chainId) => {
|
|
|
50
51
|
ChainType.EVM,
|
|
51
52
|
ChainType.SVM,
|
|
52
53
|
ChainType.UTXO,
|
|
53
|
-
ChainType.MVM
|
|
54
|
+
ChainType.MVM,
|
|
55
|
+
ChainType.TVM
|
|
54
56
|
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)),
|
|
55
57
|
orderBy: "volumeUSD24H",
|
|
56
58
|
extended: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokens.js","names":[],"sources":["../../../src/hooks/useTokens.ts"],"sourcesContent":["import {\n ChainType,\n getToken,\n getTokens,\n type TokenExtended,\n type TokensExtendedResponse,\n} from '@lifi/sdk'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { defaultChainIdsByType } from '../utils/chainType.js'\nimport { isItemAllowed } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport {\n filterAllowedTokens,\n mergeVerifiedWithSearchTokens,\n} from '../utils/token.js'\n\nconst refetchInterval = 300_000\n\nexport const useTokens = (\n formType?: FormType,\n search?: string,\n chainId?: number\n): {\n allTokens: Record<number, TokenExtended[]> | undefined\n isLoading: boolean\n isSearchLoading: boolean\n} => {\n const {\n tokens: configTokens,\n chains: chainsConfig,\n keyPrefix,\n } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n\n // Main tokens cache - verified tokens from API\n const { data: verifiedTokens, isLoading } = useQuery({\n queryKey: [getQueryKey('tokens', keyPrefix)],\n queryFn: async ({ signal }) => {\n const chainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))\n\n const tokensResponse: TokensExtendedResponse = await getTokens(\n sdkClient,\n {\n chainTypes,\n orderBy: 'volumeUSD24H',\n extended: true,\n limit: 1000,\n minPriceUSD: 0.000001,\n },\n { signal }\n )\n\n // Mark all tokens as verified\n const tokens: TokensByChain = Object.fromEntries(\n Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [\n chainId,\n tokens.map((token) => ({ ...token, verified: true })),\n ])\n )\n\n return tokens\n },\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n // Search tokens cache - unverified tokens from search\n const { data: searchTokens, isLoading: isSearchLoading } = useQuery({\n queryKey: [getQueryKey('tokens-search', keyPrefix), search, chainId],\n queryFn: async ({ queryKey, signal }) => {\n const [, searchQuery, searchChainId] = queryKey as [\n string,\n string,\n number,\n ]\n const chainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))\n\n const tokensResponse: TokensExtendedResponse = await getTokens(\n sdkClient,\n {\n chainTypes,\n orderBy: 'volumeUSD24H',\n extended: true,\n search: searchQuery,\n limit: 1000,\n minPriceUSD: 0.000001,\n },\n { signal }\n )\n\n // If the chainId is not provided, try to get it from the search query\n let _chainId = searchChainId\n if (!_chainId) {\n const chainType = getChainTypeFromAddress(searchQuery)\n if (chainType && chainType in defaultChainIdsByType) {\n _chainId = defaultChainIdsByType[chainType]\n }\n }\n\n // Fallback: If the main search returned no tokens for the specific chainId,\n // fetch a single token using the /token endpoint\n if (_chainId && searchQuery) {\n const existingTokens = tokensResponse.tokens[_chainId] || []\n if (!existingTokens.length) {\n const token = await getToken(sdkClient, _chainId, searchQuery, {\n signal,\n })\n if (token) {\n tokensResponse.tokens[_chainId] = [token]\n }\n }\n }\n\n // Mark all search tokens as unverified\n const tokens: TokensByChain = Object.fromEntries(\n Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [\n chainId,\n tokens.map((token) => ({ ...token, verified: false })),\n ])\n )\n\n return tokens\n },\n enabled: !!search,\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n // Merge tokens at read time - single place where caches are combined\n const allTokens = useMemo(() => {\n const merged = mergeVerifiedWithSearchTokens(verifiedTokens, searchTokens)\n return filterAllowedTokens(merged, configTokens, chainsConfig, formType)\n }, [verifiedTokens, searchTokens, configTokens, chainsConfig, formType])\n\n return {\n allTokens,\n isLoading,\n isSearchLoading,\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,kBAAkB;AAExB,MAAa,aACX,UACA,QACA,YAKG;CACH,MAAM,EACJ,QAAQ,cACR,QAAQ,cACR,cACE,iBAAiB;CACrB,MAAM,YAAY,cAAc;CAChC,MAAM,EAAE,4BAA4B,yBAAyB;CAG7D,MAAM,EAAE,MAAM,gBAAgB,cAAc,SAAS;EACnD,UAAU,CAAC,YAAY,UAAU,UAAU,CAAC;EAC5C,SAAS,OAAO,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"useTokens.js","names":[],"sources":["../../../src/hooks/useTokens.ts"],"sourcesContent":["import {\n ChainType,\n getToken,\n getTokens,\n type TokenExtended,\n type TokensExtendedResponse,\n} from '@lifi/sdk'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport type { TokensByChain } from '../types/token.js'\nimport { defaultChainIdsByType } from '../utils/chainType.js'\nimport { isItemAllowed } from '../utils/item.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport {\n filterAllowedTokens,\n mergeVerifiedWithSearchTokens,\n} from '../utils/token.js'\n\nconst refetchInterval = 300_000\n\nexport const useTokens = (\n formType?: FormType,\n search?: string,\n chainId?: number\n): {\n allTokens: Record<number, TokenExtended[]> | undefined\n isLoading: boolean\n isSearchLoading: boolean\n} => {\n const {\n tokens: configTokens,\n chains: chainsConfig,\n keyPrefix,\n } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n\n // Main tokens cache - verified tokens from API\n const { data: verifiedTokens, isLoading } = useQuery({\n queryKey: [getQueryKey('tokens', keyPrefix)],\n queryFn: async ({ signal }) => {\n const chainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ChainType.TVM,\n ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))\n\n const tokensResponse: TokensExtendedResponse = await getTokens(\n sdkClient,\n {\n chainTypes,\n orderBy: 'volumeUSD24H',\n extended: true,\n limit: 1000,\n minPriceUSD: 0.000001,\n },\n { signal }\n )\n\n // Mark all tokens as verified\n const tokens: TokensByChain = Object.fromEntries(\n Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [\n chainId,\n tokens.map((token) => ({ ...token, verified: true })),\n ])\n )\n\n return tokens\n },\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n // Search tokens cache - unverified tokens from search\n const { data: searchTokens, isLoading: isSearchLoading } = useQuery({\n queryKey: [getQueryKey('tokens-search', keyPrefix), search, chainId],\n queryFn: async ({ queryKey, signal }) => {\n const [, searchQuery, searchChainId] = queryKey as [\n string,\n string,\n number,\n ]\n const chainTypes = [\n ChainType.EVM,\n ChainType.SVM,\n ChainType.UTXO,\n ChainType.MVM,\n ChainType.TVM,\n ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types))\n\n const tokensResponse: TokensExtendedResponse = await getTokens(\n sdkClient,\n {\n chainTypes,\n orderBy: 'volumeUSD24H',\n extended: true,\n search: searchQuery,\n limit: 1000,\n minPriceUSD: 0.000001,\n },\n { signal }\n )\n\n // If the chainId is not provided, try to get it from the search query\n let _chainId = searchChainId\n if (!_chainId) {\n const chainType = getChainTypeFromAddress(searchQuery)\n if (chainType && chainType in defaultChainIdsByType) {\n _chainId = defaultChainIdsByType[chainType]\n }\n }\n\n // Fallback: If the main search returned no tokens for the specific chainId,\n // fetch a single token using the /token endpoint\n if (_chainId && searchQuery) {\n const existingTokens = tokensResponse.tokens[_chainId] || []\n if (!existingTokens.length) {\n const token = await getToken(sdkClient, _chainId, searchQuery, {\n signal,\n })\n if (token) {\n tokensResponse.tokens[_chainId] = [token]\n }\n }\n }\n\n // Mark all search tokens as unverified\n const tokens: TokensByChain = Object.fromEntries(\n Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [\n chainId,\n tokens.map((token) => ({ ...token, verified: false })),\n ])\n )\n\n return tokens\n },\n enabled: !!search,\n refetchInterval,\n staleTime: refetchInterval,\n })\n\n // Merge tokens at read time - single place where caches are combined\n const allTokens = useMemo(() => {\n const merged = mergeVerifiedWithSearchTokens(verifiedTokens, searchTokens)\n return filterAllowedTokens(merged, configTokens, chainsConfig, formType)\n }, [verifiedTokens, searchTokens, configTokens, chainsConfig, formType])\n\n return {\n allTokens,\n isLoading,\n isSearchLoading,\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,kBAAkB;AAExB,MAAa,aACX,UACA,QACA,YAKG;CACH,MAAM,EACJ,QAAQ,cACR,QAAQ,cACR,cACE,iBAAiB;CACrB,MAAM,YAAY,cAAc;CAChC,MAAM,EAAE,4BAA4B,yBAAyB;CAG7D,MAAM,EAAE,MAAM,gBAAgB,cAAc,SAAS;EACnD,UAAU,CAAC,YAAY,UAAU,UAAU,CAAC;EAC5C,SAAS,OAAO,EAAE,aAAa;GAS7B,MAAM,iBAAyC,MAAM,UACnD,WACA;IACE,YAXe;KACjB,UAAU;KACV,UAAU;KACV,UAAU;KACV,UAAU;KACV,UAAU;KACX,CAAC,QAAQ,cAAc,cAAc,WAAW,cAAc,MAAM,CAKvD;IACV,SAAS;IACT,UAAU;IACV,OAAO;IACP,aAAa;IACd,EACD,EAAE,QAAQ,CACX;AAUD,UAP8B,OAAO,YACnC,OAAO,QAAQ,eAAe,OAAO,CAAC,KAAK,CAAC,SAAS,YAAY,CAC/D,SACA,OAAO,KAAK,WAAW;IAAE,GAAG;IAAO,UAAU;IAAM,EAAE,CACtD,CAAC,CAGS;;EAEf;EACA,WAAW;EACZ,CAAC;CAGF,MAAM,EAAE,MAAM,cAAc,WAAW,oBAAoB,SAAS;EAClE,UAAU;GAAC,YAAY,iBAAiB,UAAU;GAAE;GAAQ;GAAQ;EACpE,SAAS,OAAO,EAAE,UAAU,aAAa;GACvC,MAAM,GAAG,aAAa,iBAAiB;GAavC,MAAM,iBAAyC,MAAM,UACnD,WACA;IACE,YAXe;KACjB,UAAU;KACV,UAAU;KACV,UAAU;KACV,UAAU;KACV,UAAU;KACX,CAAC,QAAQ,cAAc,cAAc,WAAW,cAAc,MAAM,CAKvD;IACV,SAAS;IACT,UAAU;IACV,QAAQ;IACR,OAAO;IACP,aAAa;IACd,EACD,EAAE,QAAQ,CACX;GAGD,IAAI,WAAW;AACf,OAAI,CAAC,UAAU;IACb,MAAM,YAAY,wBAAwB,YAAY;AACtD,QAAI,aAAa,aAAa,sBAC5B,YAAW,sBAAsB;;AAMrC,OAAI,YAAY;QAEV,EADmB,eAAe,OAAO,aAAa,EAAE,EACxC,QAAQ;KAC1B,MAAM,QAAQ,MAAM,SAAS,WAAW,UAAU,aAAa,EAC7D,QACD,CAAC;AACF,SAAI,MACF,gBAAe,OAAO,YAAY,CAAC,MAAM;;;AAa/C,UAP8B,OAAO,YACnC,OAAO,QAAQ,eAAe,OAAO,CAAC,KAAK,CAAC,SAAS,YAAY,CAC/D,SACA,OAAO,KAAK,WAAW;IAAE,GAAG;IAAO,UAAU;IAAO,EAAE,CACvD,CAAC,CAGS;;EAEf,SAAS,CAAC,CAAC;EACX;EACA,WAAW;EACZ,CAAC;AAQF,QAAO;EACL,WANgB,cAAc;AAE9B,UAAO,oBADQ,8BAA8B,gBAAgB,aAC5B,EAAE,cAAc,cAAc,SAAS;KACvE;GAAC;GAAgB;GAAc;GAAc;GAAc;GAAS,CAG5D;EACT;EACA;EACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTransactionDetails.js","names":[],"sources":["../../../src/hooks/useTransactionDetails.ts"],"sourcesContent":["import type { FullStatusData } from '@lifi/sdk'\nimport { getStatus, type StatusResponse } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport {\n keepPreviousData,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nexport const useTransactionDetails = (\n transactionHash?: string\n): {\n transaction: StatusResponse | undefined\n isLoading: boolean\n} => {\n const { account, accounts } = useAccount()\n const queryClient = useQueryClient()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const transactionHistoryQueryKey = useMemo(\n () => getQueryKey('transaction-history', keyPrefix),\n [keyPrefix]\n )\n\n const { data, isLoading } = useQuery({\n queryKey: [transactionHistoryQueryKey, transactionHash],\n queryFn: async ({ queryKey: [, transactionHash], signal }) => {\n if (transactionHash) {\n for (const account of accounts) {\n const cachedHistory = queryClient.getQueryData<StatusResponse[]>([\n transactionHistoryQueryKey,\n account.address,\n ])\n\n const transaction = cachedHistory?.find(\n (t) => t.sending.txHash === transactionHash\n )\n\n if (transaction) {\n return transaction\n }\n }\n\n const transaction = await getStatus(\n sdkClient,\n {\n txHash: transactionHash,\n },\n { signal }\n )\n\n const fromAddress = (transaction as FullStatusData)?.fromAddress\n\n if (fromAddress) {\n queryClient.setQueryData<StatusResponse[]>(\n [transactionHistoryQueryKey, fromAddress],\n (data) => {\n return [...data!, transaction!]\n }\n )\n }\n\n return transaction\n }\n },\n refetchInterval: 300_000,\n enabled: account.isConnected && Boolean(transactionHash),\n initialData: () => {\n for (const account of accounts) {\n const transaction = queryClient\n .getQueryData<StatusResponse[]>([\n transactionHistoryQueryKey,\n account.address,\n ])\n ?.find((t) => t.sending.txHash === transactionHash)\n if (transaction) {\n return transaction\n }\n }\n },\n placeholderData: keepPreviousData,\n })\n\n return {\n transaction: data,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,yBACX,oBAIG;CACH,MAAM,EAAE,SAAS,aAAa,YAAY;CAC1C,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAEhC,MAAM,6BAA6B,cAC3B,YAAY,uBAAuB,UAAU,EACnD,CAAC,UAAU,CACZ;CAED,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU,CAAC,4BAA4B,gBAAgB;EACvD,SAAS,OAAO,EAAE,UAAU,GAAG,kBAAkB,aAAa;AAC5D,OAAI,iBAAiB;AACnB,SAAK,MAAM,WAAW,UAAU;KAM9B,MAAM,cALgB,YAAY,aAA+B,CAC/D,4BACA,QAAQ,QACT,
|
|
1
|
+
{"version":3,"file":"useTransactionDetails.js","names":[],"sources":["../../../src/hooks/useTransactionDetails.ts"],"sourcesContent":["import type { FullStatusData } from '@lifi/sdk'\nimport { getStatus, type StatusResponse } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport {\n keepPreviousData,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { getQueryKey } from '../utils/queries.js'\n\nexport const useTransactionDetails = (\n transactionHash?: string\n): {\n transaction: StatusResponse | undefined\n isLoading: boolean\n} => {\n const { account, accounts } = useAccount()\n const queryClient = useQueryClient()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const transactionHistoryQueryKey = useMemo(\n () => getQueryKey('transaction-history', keyPrefix),\n [keyPrefix]\n )\n\n const { data, isLoading } = useQuery({\n queryKey: [transactionHistoryQueryKey, transactionHash],\n queryFn: async ({ queryKey: [, transactionHash], signal }) => {\n if (transactionHash) {\n for (const account of accounts) {\n const cachedHistory = queryClient.getQueryData<StatusResponse[]>([\n transactionHistoryQueryKey,\n account.address,\n ])\n\n const transaction = cachedHistory?.find(\n (t) => t.sending.txHash === transactionHash\n )\n\n if (transaction) {\n return transaction\n }\n }\n\n const transaction = await getStatus(\n sdkClient,\n {\n txHash: transactionHash,\n },\n { signal }\n )\n\n const fromAddress = (transaction as FullStatusData)?.fromAddress\n\n if (fromAddress) {\n queryClient.setQueryData<StatusResponse[]>(\n [transactionHistoryQueryKey, fromAddress],\n (data) => {\n return [...data!, transaction!]\n }\n )\n }\n\n return transaction\n }\n },\n refetchInterval: 300_000,\n enabled: account.isConnected && Boolean(transactionHash),\n initialData: () => {\n for (const account of accounts) {\n const transaction = queryClient\n .getQueryData<StatusResponse[]>([\n transactionHistoryQueryKey,\n account.address,\n ])\n ?.find((t) => t.sending.txHash === transactionHash)\n if (transaction) {\n return transaction\n }\n }\n },\n placeholderData: keepPreviousData,\n })\n\n return {\n transaction: data,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,yBACX,oBAIG;CACH,MAAM,EAAE,SAAS,aAAa,YAAY;CAC1C,MAAM,cAAc,gBAAgB;CACpC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAEhC,MAAM,6BAA6B,cAC3B,YAAY,uBAAuB,UAAU,EACnD,CAAC,UAAU,CACZ;CAED,MAAM,EAAE,MAAM,cAAc,SAAS;EACnC,UAAU,CAAC,4BAA4B,gBAAgB;EACvD,SAAS,OAAO,EAAE,UAAU,GAAG,kBAAkB,aAAa;AAC5D,OAAI,iBAAiB;AACnB,SAAK,MAAM,WAAW,UAAU;KAM9B,MAAM,cALgB,YAAY,aAA+B,CAC/D,4BACA,QAAQ,QACT,CAEgC,EAAE,MAChC,MAAM,EAAE,QAAQ,WAAW,gBAC7B;AAED,SAAI,YACF,QAAO;;IAIX,MAAM,cAAc,MAAM,UACxB,WACA,EACE,QAAQ,iBACT,EACD,EAAE,QAAQ,CACX;IAED,MAAM,cAAe,aAAgC;AAErD,QAAI,YACF,aAAY,aACV,CAAC,4BAA4B,YAAY,GACxC,SAAS;AACR,YAAO,CAAC,GAAG,MAAO,YAAa;MAElC;AAGH,WAAO;;;EAGX,iBAAiB;EACjB,SAAS,QAAQ,eAAe,QAAQ,gBAAgB;EACxD,mBAAmB;AACjB,QAAK,MAAM,WAAW,UAAU;IAC9B,MAAM,cAAc,YACjB,aAA+B,CAC9B,4BACA,QAAQ,QACT,CAAC,EACA,MAAM,MAAM,EAAE,QAAQ,WAAW,gBAAgB;AACrD,QAAI,YACF,QAAO;;;EAIb,iBAAiB;EAClB,CAAC;AAEF,QAAO;EACL,aAAa;EACb;EACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTransactionHistory.js","names":[],"sources":["../../../src/hooks/useTransactionHistory.ts"],"sourcesContent":["import type { FullStatusData, StatusResponse } from '@lifi/sdk'\nimport { getTransactionHistory } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport type { QueryFunction } from '@tanstack/react-query'\nimport { useQueries } from '@tanstack/react-query'\nimport { useEffect, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useRouteExecutionStoreContext } from '../stores/routes/RouteExecutionStore.js'\nimport type {\n RouteExecution,\n RouteExecutionState,\n} from '../stores/routes/types.js'\nimport { getSourceTxHash } from '../stores/routes/utils.js'\nimport { buildRouteFromTxHistory } from '../utils/converters.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useTools } from './useTools.js'\n\nexport const useTransactionHistory = (): {\n data: RouteExecution[]\n isLoading: boolean\n} => {\n const store = useRouteExecutionStoreContext()\n const { accounts } = useAccount()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const { tools } = useTools()\n\n const { data: routeExecutions, isLoading } = useQueries({\n queries: accounts.map((account) => ({\n queryKey: [\n getQueryKey('transaction-history', keyPrefix),\n account.address,\n ],\n queryFn: (async ({ queryKey: [, accountAddress], signal }) => {\n if (!accountAddress) {\n return []\n }\n const date = new Date()\n date.setFullYear(date.getFullYear() - 10)\n\n const response = await getTransactionHistory(\n sdkClient,\n {\n wallet: accountAddress,\n fromTimestamp: Math.floor(date.getTime() / 1000),\n toTimestamp: Math.floor(Date.now() / 1000),\n },\n { signal }\n )\n\n return response.transfers\n }) as QueryFunction<StatusResponse[], (string | undefined)[], never>,\n refetchInterval: 300_000,\n enabled: Boolean(account.address),\n })),\n combine: (results) => {\n const uniqueTransactions = new Map<string, StatusResponse>()\n results.forEach((result) => {\n if (result.data) {\n result.data.forEach((transaction) => {\n if (\n (transaction as FullStatusData)?.transactionId &&\n (transaction as FullStatusData)?.receiving?.chainId &&\n transaction?.sending.chainId\n ) {\n uniqueTransactions.set(\n (transaction as FullStatusData).transactionId,\n transaction\n )\n }\n })\n }\n })\n // Convert raw API transactions into RouteExecution objects.\n const data = Array.from(uniqueTransactions.values()).flatMap(\n (transaction) => {\n const routeExecution = buildRouteFromTxHistory(\n transaction as FullStatusData,\n tools\n )\n return routeExecution ? [routeExecution] : []\n }\n )\n return {\n data,\n isLoading: results.some((result) => result.isLoading),\n }\n },\n })\n\n // Stable Set — only recreated when data actually changes (TanStack Query structural sharing).\n const apiTxHashes = useMemo(\n () => new Set(routeExecutions.map((r) => getSourceTxHash(r.route))),\n [routeExecutions]\n )\n\n // Remove local store routes already indexed by the API to avoid duplicates.\n // Must be in an effect — combine runs during render, so store mutations there\n // would trigger \"Cannot update a component while rendering\" in concurrent mode.\n useEffect(() => {\n if (!apiTxHashes.size) {\n return\n }\n const { routes, deleteRoute } = store.getState() as RouteExecutionState\n for (const [id, routeExecution] of Object.entries(routes)) {\n const txHash = getSourceTxHash(\n (routeExecution as RouteExecution | undefined)?.route\n )\n if (txHash && apiTxHashes.has(txHash)) {\n deleteRoute(id)\n }\n }\n }, [apiTxHashes, store])\n\n return {\n data: routeExecutions,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,8BAGR;CACH,MAAM,QAAQ,+BAA+B;CAC7C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAChC,MAAM,EAAE,UAAU,UAAU;CAE5B,MAAM,EAAE,MAAM,iBAAiB,cAAc,WAAW;EACtD,SAAS,SAAS,KAAK,aAAa;GAClC,UAAU,CACR,YAAY,uBAAuB,UAAU,EAC7C,QAAQ,QACT;GACD,UAAU,OAAO,EAAE,UAAU,GAAG,iBAAiB,aAAa;AAC5D,QAAI,CAAC,eACH,QAAO,EAAE;IAEX,MAAM,uBAAO,IAAI,MAAM;AACvB,SAAK,YAAY,KAAK,aAAa,GAAG,GAAG;AAYzC,
|
|
1
|
+
{"version":3,"file":"useTransactionHistory.js","names":[],"sources":["../../../src/hooks/useTransactionHistory.ts"],"sourcesContent":["import type { FullStatusData, StatusResponse } from '@lifi/sdk'\nimport { getTransactionHistory } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport type { QueryFunction } from '@tanstack/react-query'\nimport { useQueries } from '@tanstack/react-query'\nimport { useEffect, useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useRouteExecutionStoreContext } from '../stores/routes/RouteExecutionStore.js'\nimport type {\n RouteExecution,\n RouteExecutionState,\n} from '../stores/routes/types.js'\nimport { getSourceTxHash } from '../stores/routes/utils.js'\nimport { buildRouteFromTxHistory } from '../utils/converters.js'\nimport { getQueryKey } from '../utils/queries.js'\nimport { useTools } from './useTools.js'\n\nexport const useTransactionHistory = (): {\n data: RouteExecution[]\n isLoading: boolean\n} => {\n const store = useRouteExecutionStoreContext()\n const { accounts } = useAccount()\n const { keyPrefix } = useWidgetConfig()\n const sdkClient = useSDKClient()\n const { tools } = useTools()\n\n const { data: routeExecutions, isLoading } = useQueries({\n queries: accounts.map((account) => ({\n queryKey: [\n getQueryKey('transaction-history', keyPrefix),\n account.address,\n ],\n queryFn: (async ({ queryKey: [, accountAddress], signal }) => {\n if (!accountAddress) {\n return []\n }\n const date = new Date()\n date.setFullYear(date.getFullYear() - 10)\n\n const response = await getTransactionHistory(\n sdkClient,\n {\n wallet: accountAddress,\n fromTimestamp: Math.floor(date.getTime() / 1000),\n toTimestamp: Math.floor(Date.now() / 1000),\n },\n { signal }\n )\n\n return response.transfers\n }) as QueryFunction<StatusResponse[], (string | undefined)[], never>,\n refetchInterval: 300_000,\n enabled: Boolean(account.address),\n })),\n combine: (results) => {\n const uniqueTransactions = new Map<string, StatusResponse>()\n results.forEach((result) => {\n if (result.data) {\n result.data.forEach((transaction) => {\n if (\n (transaction as FullStatusData)?.transactionId &&\n (transaction as FullStatusData)?.receiving?.chainId &&\n transaction?.sending.chainId\n ) {\n uniqueTransactions.set(\n (transaction as FullStatusData).transactionId,\n transaction\n )\n }\n })\n }\n })\n // Convert raw API transactions into RouteExecution objects.\n const data = Array.from(uniqueTransactions.values()).flatMap(\n (transaction) => {\n const routeExecution = buildRouteFromTxHistory(\n transaction as FullStatusData,\n tools\n )\n return routeExecution ? [routeExecution] : []\n }\n )\n return {\n data,\n isLoading: results.some((result) => result.isLoading),\n }\n },\n })\n\n // Stable Set — only recreated when data actually changes (TanStack Query structural sharing).\n const apiTxHashes = useMemo(\n () => new Set(routeExecutions.map((r) => getSourceTxHash(r.route))),\n [routeExecutions]\n )\n\n // Remove local store routes already indexed by the API to avoid duplicates.\n // Must be in an effect — combine runs during render, so store mutations there\n // would trigger \"Cannot update a component while rendering\" in concurrent mode.\n useEffect(() => {\n if (!apiTxHashes.size) {\n return\n }\n const { routes, deleteRoute } = store.getState() as RouteExecutionState\n for (const [id, routeExecution] of Object.entries(routes)) {\n const txHash = getSourceTxHash(\n (routeExecution as RouteExecution | undefined)?.route\n )\n if (txHash && apiTxHashes.has(txHash)) {\n deleteRoute(id)\n }\n }\n }, [apiTxHashes, store])\n\n return {\n data: routeExecutions,\n isLoading,\n }\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,8BAGR;CACH,MAAM,QAAQ,+BAA+B;CAC7C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,EAAE,cAAc,iBAAiB;CACvC,MAAM,YAAY,cAAc;CAChC,MAAM,EAAE,UAAU,UAAU;CAE5B,MAAM,EAAE,MAAM,iBAAiB,cAAc,WAAW;EACtD,SAAS,SAAS,KAAK,aAAa;GAClC,UAAU,CACR,YAAY,uBAAuB,UAAU,EAC7C,QAAQ,QACT;GACD,UAAU,OAAO,EAAE,UAAU,GAAG,iBAAiB,aAAa;AAC5D,QAAI,CAAC,eACH,QAAO,EAAE;IAEX,MAAM,uBAAO,IAAI,MAAM;AACvB,SAAK,YAAY,KAAK,aAAa,GAAG,GAAG;AAYzC,YAAO,MAVgB,sBACrB,WACA;KACE,QAAQ;KACR,eAAe,KAAK,MAAM,KAAK,SAAS,GAAG,IAAK;KAChD,aAAa,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;KAC3C,EACD,EAAE,QAAQ,CACX,EAEe;;GAElB,iBAAiB;GACjB,SAAS,QAAQ,QAAQ,QAAQ;GAClC,EAAE;EACH,UAAU,YAAY;GACpB,MAAM,qCAAqB,IAAI,KAA6B;AAC5D,WAAQ,SAAS,WAAW;AAC1B,QAAI,OAAO,KACT,QAAO,KAAK,SAAS,gBAAgB;AACnC,SACG,aAAgC,iBAChC,aAAgC,WAAW,WAC5C,aAAa,QAAQ,QAErB,oBAAmB,IAChB,YAA+B,eAChC,YACD;MAEH;KAEJ;AAWF,UAAO;IACL,MAVW,MAAM,KAAK,mBAAmB,QAAQ,CAAC,CAAC,SAClD,gBAAgB;KACf,MAAM,iBAAiB,wBACrB,aACA,MACD;AACD,YAAO,iBAAiB,CAAC,eAAe,GAAG,EAAE;MAI3C;IACJ,WAAW,QAAQ,MAAM,WAAW,OAAO,UAAU;IACtD;;EAEJ,CAAC;CAGF,MAAM,cAAc,cACZ,IAAI,IAAI,gBAAgB,KAAK,MAAM,gBAAgB,EAAE,MAAM,CAAC,CAAC,EACnE,CAAC,gBAAgB,CAClB;AAKD,iBAAgB;AACd,MAAI,CAAC,YAAY,KACf;EAEF,MAAM,EAAE,QAAQ,gBAAgB,MAAM,UAAU;AAChD,OAAK,MAAM,CAAC,IAAI,mBAAmB,OAAO,QAAQ,OAAO,EAAE;GACzD,MAAM,SAAS,gBACZ,gBAA+C,MACjD;AACD,OAAI,UAAU,YAAY,IAAI,OAAO,CACnC,aAAY,GAAG;;IAGlB,CAAC,aAAa,MAAM,CAAC;AAExB,QAAO;EACL,MAAM;EACN;EACD"}
|