@lifi/widget 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/AppDefault.js +14 -0
- package/dist/esm/AppDefault.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInput.js +2 -1
- package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +4 -2
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js.map +1 -1
- package/dist/esm/components/AmountInput/PriceFormHelperText.js +4 -2
- package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
- package/dist/esm/components/AmountInputCard/AmountInputCard.style.js +98 -0
- package/dist/esm/components/AmountInputCard/AmountInputCard.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +25 -0
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.js +35 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js +11 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/FiatValueToggle.js +41 -0
- package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.js +80 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.style.js +43 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +137 -0
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -0
- package/dist/esm/components/AmountInputCard/SendAmountCard.js +102 -0
- package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -0
- package/dist/esm/components/Avatar/Avatar.js +12 -3
- package/dist/esm/components/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/Chains/VirtualizedChainList.js +2 -1
- package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
- package/dist/esm/components/Header/HeaderNavigationTabs.js +14 -1
- package/dist/esm/components/Header/HeaderNavigationTabs.js.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.style.js +1 -1
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js +99 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js +52 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.js +115 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js +89 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPricePresets.js +91 -0
- package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -0
- package/dist/esm/components/RouteCard/RouteProviderCard.js +118 -0
- package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -0
- package/dist/esm/components/Routes/LimitOrderRoutes.js +34 -0
- package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -0
- package/dist/esm/components/Routes/Routes.js +2 -2
- package/dist/esm/components/Routes/Routes.js.map +1 -1
- package/dist/esm/components/SettingsPanel/SettingsPanel.js +51 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.style.js +33 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.style.js.map +1 -0
- package/dist/esm/components/SettingsPanel/utils.js +14 -0
- package/dist/esm/components/SettingsPanel/utils.js.map +1 -0
- package/dist/esm/components/SwapButton/SwapButton.js +50 -0
- package/dist/esm/components/SwapButton/SwapButton.js.map +1 -0
- package/dist/esm/components/SwapButton/SwapButton.style.js +24 -0
- package/dist/esm/components/SwapButton/SwapButton.style.js.map +1 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.js +52 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.style.js +39 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.style.js.map +1 -0
- 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/useChainSearch.js +2 -1
- package/dist/esm/hooks/useChainSearch.js.map +1 -1
- package/dist/esm/hooks/useLimitMarketRate.js +24 -0
- package/dist/esm/hooks/useLimitMarketRate.js.map +1 -0
- package/dist/esm/hooks/useLinkedLimitFields.js +49 -0
- package/dist/esm/hooks/useLinkedLimitFields.js.map +1 -0
- package/dist/esm/hooks/useRoutes.js +23 -6
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +16 -14
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useWideVariant.js +5 -2
- package/dist/esm/hooks/useWideVariant.js.map +1 -1
- package/dist/esm/i18n/en.json +22 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/pages/MainPage/LimitPageContent.js +23 -0
- package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -0
- package/dist/esm/pages/MainPage/MainPage.js +19 -22
- package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
- package/dist/esm/pages/MainPage/MainPageActions.js +28 -0
- package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -0
- package/dist/esm/pages/MainPage/ReviewButton.js +9 -2
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/RoutePriorityPage.js +48 -0
- package/dist/esm/pages/RoutePriorityPage.js.map +1 -0
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +12 -27
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js +133 -0
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -0
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +14 -72
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js +26 -14
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
- package/dist/esm/pages/SettingsPage/ThemeSettings.js +4 -0
- package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionReview.js +4 -1
- package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.js +1 -1
- package/dist/esm/providers/I18nProvider/enResource.d.ts +1 -1
- package/dist/esm/providers/I18nProvider/enResource.js +1 -1
- package/dist/esm/providers/I18nProvider/types.d.ts +2 -2
- package/dist/esm/providers/SDKClientProvider.js +25 -24
- package/dist/esm/providers/SDKClientProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +22 -21
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js +14 -3
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/createFormStore.js +6 -2
- package/dist/esm/stores/form/createFormStore.js.map +1 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +3 -0
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
- package/dist/esm/stores/form/types.d.ts +9 -1
- package/dist/esm/stores/form/types.d.ts.map +1 -1
- package/dist/esm/stores/form/types.js.map +1 -1
- package/dist/esm/stores/form/useClearAmountFields.js +1 -0
- package/dist/esm/stores/form/useClearAmountFields.js.map +1 -1
- package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js +4 -2
- package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
- package/dist/esm/stores/navigationTabs/utils.js +38 -8
- package/dist/esm/stores/navigationTabs/utils.js.map +1 -1
- package/dist/esm/types/events.d.ts +10 -1
- package/dist/esm/types/events.d.ts.map +1 -1
- package/dist/esm/types/events.js +2 -0
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/types/widget.d.ts +9 -0
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/format.d.ts +1 -1
- package/dist/esm/utils/format.d.ts.map +1 -1
- package/dist/esm/utils/format.js +2 -2
- package/dist/esm/utils/format.js.map +1 -1
- package/dist/esm/utils/limitOrder.js +61 -0
- package/dist/esm/utils/limitOrder.js.map +1 -0
- package/dist/esm/utils/navigationRoutes.d.ts +2 -0
- package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
- package/dist/esm/utils/navigationRoutes.js +6 -0
- package/dist/esm/utils/navigationRoutes.js.map +1 -1
- package/package.json +11 -11
- package/src/AppDefault.tsx +16 -0
- package/src/components/AmountInput/AmountInputEndAdornment.style.ts +1 -1
- package/src/components/AmountInput/AmountInputEndAdornment.tsx +5 -2
- package/src/components/AmountInputCard/AmountInputCard.style.tsx +157 -0
- package/src/components/AmountInputCard/AmountInputCardPair.tsx +25 -0
- package/src/components/AmountInputCard/BalanceDisplay.style.tsx +9 -0
- package/src/components/AmountInputCard/BalanceDisplay.tsx +46 -0
- package/src/components/AmountInputCard/FiatValueToggle.tsx +55 -0
- package/src/components/AmountInputCard/PercentageChips.style.tsx +60 -0
- package/src/components/AmountInputCard/PercentageChips.tsx +100 -0
- package/src/components/AmountInputCard/ReceiveAmountCard.tsx +219 -0
- package/src/components/AmountInputCard/SendAmountCard.tsx +179 -0
- package/src/components/Avatar/Avatar.tsx +8 -3
- package/src/components/Header/HeaderNavigationTabs.tsx +19 -2
- package/src/components/LimitOrderSettings/LimitOrderSettings.style.tsx +69 -0
- package/src/components/LimitOrderSettings/LimitOrderSettings.tsx +124 -0
- package/src/components/LimitPriceCard/LimitPriceCard.style.tsx +103 -0
- package/src/components/LimitPriceCard/LimitPriceCard.tsx +153 -0
- package/src/components/LimitPriceCard/LimitPricePresets.tsx +139 -0
- package/src/components/RouteCard/RouteProviderCard.tsx +113 -0
- package/src/components/Routes/LimitOrderRoutes.tsx +64 -0
- package/src/components/Routes/Routes.tsx +3 -2
- package/src/components/SettingsPanel/SettingsPanel.style.tsx +41 -0
- package/src/components/SettingsPanel/SettingsPanel.tsx +73 -0
- package/src/components/SettingsPanel/utils.ts +27 -0
- package/src/components/SwapButton/SwapButton.style.tsx +28 -0
- package/src/components/SwapButton/SwapButton.tsx +71 -0
- package/src/components/TokenPillButton/TokenPillButton.style.tsx +50 -0
- package/src/components/TokenPillButton/TokenPillButton.tsx +81 -0
- package/src/config/version.ts +1 -1
- package/src/hooks/useLimitMarketRate.ts +39 -0
- package/src/hooks/useLinkedLimitFields.ts +74 -0
- package/src/hooks/useRoutes.ts +45 -4
- package/src/hooks/useWideVariant.ts +8 -2
- package/src/pages/MainPage/LimitPageContent.tsx +18 -0
- package/src/pages/MainPage/MainPage.tsx +43 -30
- package/src/pages/MainPage/MainPageActions.tsx +35 -0
- package/src/pages/MainPage/ReviewButton.tsx +13 -1
- package/src/pages/RoutePriorityPage.tsx +55 -0
- package/src/pages/SettingsPage/RoutePrioritySettings.tsx +14 -38
- package/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx +176 -0
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +32 -25
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +14 -128
- package/src/pages/SettingsPage/ThemeSettings.tsx +4 -0
- package/src/stores/form/URLSearchParamsBuilder.tsx +25 -3
- package/src/stores/form/createFormStore.ts +7 -3
- package/src/stores/form/getDefaultValuesFromQueryString.ts +11 -0
- package/src/stores/form/types.ts +14 -1
- package/src/stores/form/useClearAmountFields.ts +1 -0
- package/src/stores/navigationTabs/types.ts +6 -0
- package/src/stores/navigationTabs/useNavigationTabsStore.tsx +8 -3
- package/src/stores/navigationTabs/utils.ts +67 -5
- package/src/types/events.ts +12 -0
- package/src/types/widget.ts +9 -0
- package/src/utils/format.ts +6 -2
- package/src/utils/limitOrder.ts +88 -0
- package/src/utils/navigationRoutes.ts +6 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useWidgetEvents } from "./useWidgetEvents.js";
|
|
2
2
|
import "../types/events.js";
|
|
3
3
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
4
|
+
import { useNavigationTabsStore } from "../stores/navigationTabs/useNavigationTabsStore.js";
|
|
4
5
|
import { useSwapOnly } from "./useSwapOnly.js";
|
|
5
6
|
import { useSDKClient } from "../providers/SDKClientProvider.js";
|
|
6
7
|
import { getQueryKey } from "../utils/queries.js";
|
|
@@ -28,6 +29,7 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
28
29
|
const queryClient = useQueryClient();
|
|
29
30
|
const emitter = useWidgetEvents();
|
|
30
31
|
const swapOnly = useSwapOnly();
|
|
32
|
+
const isPrivate = useNavigationTabsStore((state) => state.activeTab === "private");
|
|
31
33
|
const { disabledBridges, disabledExchanges, enabledBridges, enabledExchanges, enabledAutoRefuel, routePriority, slippage } = useSettings([
|
|
32
34
|
"disabledBridges",
|
|
33
35
|
"disabledExchanges",
|
|
@@ -38,7 +40,9 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
38
40
|
"slippage"
|
|
39
41
|
]);
|
|
40
42
|
const [fromTokenAmount] = useDebouncedWatch(500, "fromAmount");
|
|
41
|
-
const [
|
|
43
|
+
const [toTokenAmount] = useDebouncedWatch(500, "toAmount");
|
|
44
|
+
const [fromChainId, fromTokenAddress, toAddress, toChainId, toTokenAddress, contractCalls] = useFieldValues("fromChain", "fromToken", "toAddress", "toChain", "toToken", "contractCalls");
|
|
45
|
+
const [validUntilDuration, partiallyFillable] = useFieldValues("validUntil", "partiallyFillable");
|
|
42
46
|
const { token: fromToken } = useToken(fromChainId, fromTokenAddress);
|
|
43
47
|
const { token: toToken } = useToken(toChainId, toTokenAddress);
|
|
44
48
|
const { chain: fromChain } = useChain(fromChainId);
|
|
@@ -48,7 +52,7 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
48
52
|
const { isGaslessStep, disableMessageSigning } = useEthereumContext();
|
|
49
53
|
const { account } = useAccount({ chainType: fromChain?.chainType });
|
|
50
54
|
const { isBatchingSupported, isBatchingSupportedLoading } = useIsBatchingSupported(fromChain, account.address);
|
|
51
|
-
const hasAmount = Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0;
|
|
55
|
+
const hasAmount = mode === "limit" ? Number(fromTokenAmount) > 0 && Number(toTokenAmount) > 0 : Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0;
|
|
52
56
|
const contractCallQuoteEnabled = mode === "custom" ? Boolean(contractCalls && account.address) : true;
|
|
53
57
|
const hasToAddressAndChainTypeSatisfied = !!toChain && !!toAddress && getChainTypeFromAddress(toAddress) === toChain.chainType;
|
|
54
58
|
const isToAddressSatisfied = toAddress ? hasToAddressAndChainTypeSatisfied : true;
|
|
@@ -67,6 +71,8 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
67
71
|
toChain?.id,
|
|
68
72
|
toToken?.address,
|
|
69
73
|
toTokenAmount,
|
|
74
|
+
validUntilDuration,
|
|
75
|
+
partiallyFillable,
|
|
70
76
|
contractCalls,
|
|
71
77
|
slippage,
|
|
72
78
|
swapOnly,
|
|
@@ -82,6 +88,7 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
82
88
|
feeConfig?.fee,
|
|
83
89
|
disableMessageSigning,
|
|
84
90
|
!!isBatchingSupported,
|
|
91
|
+
isPrivate,
|
|
85
92
|
observableRoute?.id
|
|
86
93
|
], [
|
|
87
94
|
keyPrefix,
|
|
@@ -93,6 +100,8 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
93
100
|
toChain?.id,
|
|
94
101
|
toToken?.address,
|
|
95
102
|
toTokenAmount,
|
|
103
|
+
validUntilDuration,
|
|
104
|
+
partiallyFillable,
|
|
96
105
|
contractCalls,
|
|
97
106
|
slippage,
|
|
98
107
|
swapOnly,
|
|
@@ -109,14 +118,15 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
109
118
|
feeConfig?.fee,
|
|
110
119
|
disableMessageSigning,
|
|
111
120
|
isBatchingSupported,
|
|
121
|
+
isPrivate,
|
|
112
122
|
observableRoute?.id
|
|
113
123
|
]);
|
|
114
124
|
const { getIntermediateRoutes, setIntermediateRoutes } = useIntermediateRoutesStore();
|
|
115
125
|
const { data, isLoading, isFetching, isFetched, dataUpdatedAt, refetch } = useQuery({
|
|
116
126
|
queryKey,
|
|
117
|
-
queryFn: async ({ queryKey: [_, fromAddress, fromChainId, fromTokenAddress, fromTokenAmount, toAddress, toChainId, toTokenAddress, toTokenAmount, contractCalls, slippage = void 0, swapOnly, disabledBridges, disabledExchanges, allowedBridges, allowedExchanges, routePriority, mode, allowSwitchChain, enabledRefuel, gasRecommendationFromAmount, configuredFee, disableMessageSigning, isBatchingSupported, _observableRouteId], signal }) => {
|
|
127
|
+
queryFn: async ({ queryKey: [_, fromAddress, fromChainId, fromTokenAddress, fromTokenAmount, toAddress, toChainId, toTokenAddress, toTokenAmount, validUntilDuration, partiallyFillable, contractCalls, slippage = void 0, swapOnly, disabledBridges, disabledExchanges, allowedBridges, allowedExchanges, routePriority, mode, allowSwitchChain, enabledRefuel, gasRecommendationFromAmount, configuredFee, disableMessageSigning, isBatchingSupported, isPrivate, _observableRouteId], signal }) => {
|
|
118
128
|
const fromAmount = parseUnits(fromTokenAmount, fromToken.decimals);
|
|
119
|
-
const toAmount = parseUnits(toTokenAmount, toToken.decimals);
|
|
129
|
+
const toAmount = toTokenAmount ? parseUnits(toTokenAmount, toToken.decimals) : void 0;
|
|
120
130
|
const formattedSlippage = slippage ? Number.parseFloat(slippage) / 100 : void 0;
|
|
121
131
|
const allowBridges = swapOnly ? [] : observableRoute ? observableRoute.steps.flatMap((step) => step.includedSteps.reduce((toolKeys, includedStep) => {
|
|
122
132
|
if (includedStep.type === "cross") toolKeys.push(includedStep.toolDetails.key);
|
|
@@ -170,7 +180,12 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
170
180
|
if (fromChainId === toChainId && fromTokenAddress === toTokenAddress && !(mode === "custom" && modeOptions?.custom?.type === "deposit")) return;
|
|
171
181
|
const isObservableRelayerRoute = observableRoute?.steps?.some((step) => !!isGaslessStep?.(step, fromChain));
|
|
172
182
|
const shouldUseMainRoutes = !observableRoute || !isObservableRelayerRoute;
|
|
173
|
-
const shouldUseRelayerQuote = fromAddress && fromChain?.chainType === ChainType.EVM && fromChain.permit2 && fromChain.permit2Proxy && fromChain.relayerSupported && fromChain.nativeToken.address !== fromTokenAddress && useRelayerRoutes && !isBatchingSupported && (!observableRoute || isObservableRelayerRoute);
|
|
183
|
+
const shouldUseRelayerQuote = mode !== "limit" && fromAddress && fromChain?.chainType === ChainType.EVM && fromChain.permit2 && fromChain.permit2Proxy && fromChain.relayerSupported && fromChain.nativeToken.address !== fromTokenAddress && useRelayerRoutes && !isBatchingSupported && (!observableRoute || isObservableRelayerRoute);
|
|
184
|
+
const limitOrderRouteParams = mode === "limit" ? {
|
|
185
|
+
toAmount: toAmount?.toString(),
|
|
186
|
+
validUntil: Math.floor(Date.now() / 1e3) + validUntilDuration,
|
|
187
|
+
partiallyFillable
|
|
188
|
+
} : void 0;
|
|
174
189
|
const mainRoutesPromise = shouldUseMainRoutes ? getRoutes(sdkClient, {
|
|
175
190
|
fromAddress,
|
|
176
191
|
fromAmount: fromAmount.toString(),
|
|
@@ -180,6 +195,7 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
180
195
|
toChainId,
|
|
181
196
|
toTokenAddress,
|
|
182
197
|
fromAmountForGas: enabledRefuel && gasRecommendationFromAmount ? gasRecommendationFromAmount : void 0,
|
|
198
|
+
...limitOrderRouteParams,
|
|
183
199
|
options: {
|
|
184
200
|
allowSwitchChain: mode === "refuel" ? false : allowSwitchChain,
|
|
185
201
|
bridges: allowBridges?.length || disabledBridges.length ? {
|
|
@@ -193,7 +209,8 @@ const useRoutes = ({ observableRoute } = {}) => {
|
|
|
193
209
|
order: routePriority,
|
|
194
210
|
slippage: formattedSlippage,
|
|
195
211
|
fee: calculatedFee || configuredFee,
|
|
196
|
-
executionType: disableMessageSigning ? "transaction" : "all"
|
|
212
|
+
executionType: disableMessageSigning ? "transaction" : "all",
|
|
213
|
+
...isPrivate && { private: true }
|
|
197
214
|
}
|
|
198
215
|
}, { signal }) : Promise.resolve(null);
|
|
199
216
|
const relayerQuotePromise = shouldUseRelayerQuote ? getRelayerQuote(sdkClient, {
|
|
@@ -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 mode,\n modeOptions,\n contractTool,\n bridges,\n exchanges,\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 mode === '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 mode,\n allowSwitchChain,\n enabledRefuel && enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.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 mode,\n allowSwitchChain,\n enabledRefuel,\n enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.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 mode,\n allowSwitchChain,\n enabledRefuel,\n gasRecommendationFromAmount,\n configuredFee,\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 (mode === '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 || configuredFee,\n },\n { signal }\n )\n\n contractCallQuote.action.toToken = toToken!\n\n const customStep =\n mode === '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 mode is custom and modeOptions custom type is deposit\n if (\n fromChainId === toChainId &&\n fromTokenAddress === toTokenAddress &&\n !(mode === 'custom' && modeOptions?.custom?.type === '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 mode === '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 || configuredFee,\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 || configuredFee,\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 { useNavigationTabsStore } from '../stores/navigationTabs/useNavigationTabsStore.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 mode,\n modeOptions,\n contractTool,\n bridges,\n exchanges,\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 isPrivate = useNavigationTabsStore(\n (state) => state.activeTab === 'private'\n )\n\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 // Debounce toAmount like fromAmount to avoid a request per keystroke\n const [toTokenAmount] = useDebouncedWatch(500, 'toAmount')\n const [\n fromChainId,\n fromTokenAddress,\n toAddress,\n toChainId,\n toTokenAddress,\n contractCalls,\n ] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toAddress',\n 'toChain',\n 'toToken',\n 'contractCalls'\n )\n const [validUntilDuration, partiallyFillable] = useFieldValues(\n 'validUntil',\n 'partiallyFillable'\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 // In limit mode toAmount is the user's limit target, derived from the sell\n // amount and limit price. It's keyed and sent to the backend so changing the\n // limit fetches a fresh quote. The receive card is read-only (it displays the\n // quote and never writes toAmount back), so keying on it can't loop. Both a\n // sell amount and a limit price (→ toAmount) are required before fetching.\n const hasAmount =\n mode === 'limit'\n ? Number(fromTokenAmount) > 0 && Number(toTokenAmount) > 0\n : Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0\n\n const contractCallQuoteEnabled: boolean =\n mode === '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 validUntilDuration,\n partiallyFillable,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n mode,\n allowSwitchChain,\n enabledRefuel && enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee,\n disableMessageSigning,\n !!isBatchingSupported,\n isPrivate,\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 validUntilDuration,\n partiallyFillable,\n contractCalls,\n slippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n mode,\n allowSwitchChain,\n enabledRefuel,\n enabledAutoRefuel,\n gasRecommendationFromAmount,\n feeConfig?.fee,\n disableMessageSigning,\n isBatchingSupported,\n isPrivate,\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 validUntilDuration,\n partiallyFillable,\n contractCalls,\n slippage = defaultSlippage,\n swapOnly,\n disabledBridges,\n disabledExchanges,\n allowedBridges,\n allowedExchanges,\n routePriority,\n mode,\n allowSwitchChain,\n enabledRefuel,\n gasRecommendationFromAmount,\n configuredFee,\n disableMessageSigning,\n isBatchingSupported,\n isPrivate,\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 = toTokenAmount\n ? parseUnits(toTokenAmount, toToken!.decimals)\n : undefined\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 (mode === '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 || configuredFee,\n },\n { signal }\n )\n\n contractCallQuote.action.toToken = toToken!\n\n const customStep =\n mode === '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 mode is custom and modeOptions custom type is deposit\n if (\n fromChainId === toChainId &&\n fromTokenAddress === toTokenAddress &&\n !(mode === 'custom' && modeOptions?.custom?.type === '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 // Relayer quotes don't support limit-order params\n mode !== 'limit' &&\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 limitOrderRouteParams =\n mode === 'limit'\n ? {\n toAmount: toAmount?.toString(),\n validUntil: Math.floor(Date.now() / 1000) + validUntilDuration,\n partiallyFillable: partiallyFillable,\n }\n : undefined\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 ...limitOrderRouteParams,\n options: {\n allowSwitchChain:\n mode === '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 || configuredFee,\n executionType: disableMessageSigning ? 'transaction' : 'all',\n ...(isPrivate && { private: true }),\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 || configuredFee,\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":";;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAM,cAAc;AAMpB,MAAa,aAAa,EACxB,oBACe,CAAC,MAYb;CACH,MAAM,EACJ,MACA,aACA,cACA,SACA,WACA,WACA,kBACA,cACE,gBAAgB;CACpB,MAAM,YAAY,aAAa;CAC/B,MAAM,qBAAqB,sBAAsB;CACjD,MAAM,cAAc,eAAe;CACnC,MAAM,UAAU,gBAAgB;CAChC,MAAM,WAAW,YAAY;CAC7B,MAAM,YAAY,wBACf,UAAU,MAAM,cAAc,SACjC;CAEA,MAAM,EACJ,iBACA,mBACA,gBACA,kBACA,mBACA,eACA,aACE,YAAY;EACd;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,MAAM,CAAC,mBAAmB,kBAAkB,KAAK,YAAY;CAE7D,MAAM,CAAC,iBAAiB,kBAAkB,KAAK,UAAU;CACzD,MAAM,CACJ,aACA,kBACA,WACA,WACA,gBACA,iBACE,eACF,aACA,aACA,aACA,WACA,WACA,eACF;CACA,MAAM,CAAC,oBAAoB,qBAAqB,eAC9C,cACA,mBACF;CACA,MAAM,EAAE,OAAO,cAAc,SAAS,aAAa,gBAAgB;CACnE,MAAM,EAAE,OAAO,YAAY,SAAS,WAAW,cAAc;CAC7D,MAAM,EAAE,OAAO,cAAc,SAAS,WAAW;CACjD,MAAM,EAAE,OAAO,YAAY,SAAS,SAAS;CAC7C,MAAM,EAAE,SAAS,eAAe,YAAY,gCAC1C,aAAa;CACf,MAAM,EAAE,4BAA4B,wBAAwB;CAC5D,MAAM,EAAE,eAAe,0BAA0B,mBAAmB;CACpE,MAAM,EAAE,YAAY,WAAW,EAAE,WAAW,WAAW,UAAU,CAAC;CAClE,MAAM,EAAE,qBAAqB,+BAC3B,uBAAuB,WAAW,QAAQ,OAAO;CAOnD,MAAM,YACJ,SAAS,UACL,OAAO,eAAe,IAAI,KAAK,OAAO,aAAa,IAAI,IACvD,OAAO,eAAe,IAAI,KAAK,OAAO,aAAa,IAAI;CAE7D,MAAM,2BACJ,SAAS,WAAW,QAAQ,iBAAiB,QAAQ,OAAO,IAAI;CAIlE,MAAM,oCACJ,CAAC,CAAC,WACF,CAAC,CAAC,aACF,wBAAwB,SAAS,MAAM,QAAQ;CAEjD,MAAM,uBAAuB,YACzB,oCACA;CAGJ,MAAM,kBAAkB,aAAa,KAAA;CAGrC,MAAM,iBACJ,SAAS,OAAO,UAAU,SAAS,MAAM,SAAS,iBAAiB,KAAA;CACrE,MAAM,mBACJ,WAAW,OAAO,UAAU,WAAW,MAAM,SACzC,mBACA,KAAA;CACN,MAAM,mBAAmB,UAAU,QAAQ,cAAc;CAEzD,MAAM,YACJ,QAAQ,OAAO,WAAW,EAAE,CAAC,KAC7B,QAAQ,OAAO,SAAS,EAAE,CAAC,KAC3B,QAAQ,WAAW,OAAO,KAC1B,QAAQ,SAAS,OAAO,KACxB,CAAC,OAAO,MAAM,QAAQ,KACtB,aACA,wBACA,4BACA,CAAC;CAGH,MAAM,WAAW,cAEb;EACE,YAAY,UAAU,SAAS;EAC/B,QAAQ;EACR,WAAW;EACX,WAAW;EACX;EACA;EACA,SAAS;EACT,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,iBAAiB;EACjB;EACA,WAAW;EACX;EACA,CAAC,CAAC;EACF;EACA,iBAAiB;CACnB,GACF;EACE;EACA,QAAQ;EACR,WAAW;EACX,WAAW;EACX;EACA;EACA,SAAS;EACT,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;EACA;EACA,iBAAiB;CACnB,CACF;CAEA,MAAM,EAAE,uBAAuB,0BAC7B,2BAA2B;CAE7B,MAAM,EAAE,MAAM,WAAW,YAAY,WAAW,eAAe,YAC7D,SAAS;EACP;EACA,SAAS,OAAO,EACd,UAAU,CACR,GACA,aACA,aACA,kBACA,iBACA,WACA,WACA,gBACA,eACA,oBACA,mBACA,eACA,WAAA,KAAA,GACA,UACA,iBACA,mBACA,gBACA,kBACA,eACA,MACA,kBACA,eACA,6BACA,eACA,uBACA,qBACA,WAEA,qBAEF,aACI;GACJ,MAAM,aAAa,WAAW,iBAAiB,UAAW,QAAQ;GAClE,MAAM,WAAW,gBACb,WAAW,eAAe,QAAS,QAAQ,IAC3C,KAAA;GACJ,MAAM,oBAAoB,WACtB,OAAO,WAAW,QAAQ,IAAI,MAAA,KAAA;GAGlC,MAAM,eAAe,WACjB,CAAC,IACD,kBACE,gBAAgB,MAAM,SAAS,SAC7B,KAAK,cAAc,QAAQ,UAAU,iBAAiB;IACpD,IAAI,aAAa,SAAS,SACxB,SAAS,KAAK,aAAa,YAAY,GAAG;IAE5C,OAAO;GACT,GAAG,CAAC,CAAa,CACnB,IACA;GACN,MAAM,iBAAiB,kBACnB,gBAAgB,MAAM,SAAS,SAC7B,KAAK,cAAc,QAAQ,UAAU,iBAAiB;IACpD,IAAI,aAAa,SAAS,QACxB,SAAS,KAAK,aAAa,YAAY,GAAG;IAE5C,OAAO;GACT,GAAG,CAAC,CAAa,CACnB,IACA;GAEJ,MAAM,gBAAgB,MAAM,WAAW,eAAe;IACzC;IACF;IACE;IACF;IACT;IACA;IACA;IACA;IACA,UAAU;GACZ,CAAC;GAED,IAAI,SAAS,YAAY,iBAAiB,UAAU;IAClD,MAAM,oBAAoB,MAAM,sBAC9B,WACA;KAEe;KACb,WAAW;KACX,WAAW;KACX,UAAU,SAAS,SAAS;KAC5B,SAAS;KACT,SAAS;KACT;KACA,aAAa,gBAAgB,SAAS,kBAAkB,KAAA;KACxD,eAAe,kBAAkB,SAC7B,oBACA,KAAA;KACJ;KACA;KACA,mBAAmB;KACnB,UAAU;KACV,KAAK,iBAAiB;IACxB,GACA,EAAE,OAAO,CACX;IAEA,kBAAkB,OAAO,UAAU;IAEnC,MAAM,aACJ,SAAS,WACL,kBAAkB,eAAe,MAC9B,SAAS,KAAK,SAAS,QAC1B,IACA,KAAA;IAEN,IAAI,cAAc,cAAc;KAC9B,MAAM,cAAc;MAClB,KAAK,aAAa;MAClB,MAAM,aAAa;MACnB,SAAS,aAAa;KACxB;KACA,WAAW,cAAc;KACzB,kBAAkB,cAAc;IAClC;IAIA,OAAO,CAFc,oBAAoB,iBAE7B,CAAC;GACf;GAIA,IACE,gBAAgB,aAChB,qBAAqB,kBACrB,EAAE,SAAS,YAAY,aAAa,QAAQ,SAAS,YAErD;GAGF,MAAM,2BAA2B,iBAAiB,OAAO,MACtD,SAAS,CAAC,CAAC,gBAAgB,MAAM,SAAS,CAC7C;GAEA,MAAM,sBACJ,CAAC,mBAAmB,CAAC;GACvB,MAAM,wBAEJ,SAAS,WACT,eACA,WAAW,cAAc,UAAU,OACnC,UAAU,WACV,UAAU,gBACV,UAAU,oBACV,UAAU,YAAY,YAAY,oBAClC,oBACA,CAAC,wBACA,CAAC,mBAAmB;GAEvB,MAAM,wBACJ,SAAS,UACL;IACE,UAAU,UAAU,SAAS;IAC7B,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI;IACzB;GACrB,IACA,KAAA;GAEN,MAAM,oBAAoB,sBACtB,UACE,WACA;IACE;IACA,YAAY,WAAW,SAAS;IAChC;IACA;IACA;IACA;IACA;IACA,kBACE,iBAAiB,8BACb,8BACA,KAAA;IACN,GAAG;IACH,SAAS;KACP,kBACE,SAAS,WAAW,QAAQ;KAC9B,SACE,cAAc,UAAU,gBAAgB,SACpC;MACE,OAAO;MACP,MAAM,gBAAgB,SAClB,kBACA,KAAA;KACN,IACA,KAAA;KACN,WACE,gBAAgB,UAAU,kBAAkB,SACxC;MACE,OAAO;MACP,MAAM,kBAAkB,SACpB,oBACA,KAAA;KACN,IACA,KAAA;KACN,OAAO;KACP,UAAU;KACV,KAAK,iBAAiB;KACtB,eAAe,wBAAwB,gBAAgB;KACvD,GAAI,aAAa,EAAE,SAAS,KAAK;IACnC;GACF,GACA,EAAE,OAAO,CACX,IACA,QAAQ,QAAQ,IAAI;GAExB,MAAM,sBAAsB,wBACxB,gBACE,WACA;IACE;IACA,YAAY,WAAW,SAAS;IAChC,WAAW;IACX,WAAW;IACX;IACA,SAAS;IACT,SAAS;IACT,kBACE,iBAAiB,8BACb,8BACA,KAAA;IACN,OAAO;IACP,UAAU;IACV,KAAK,iBAAiB;IACtB,GAAI,cAAc,UAAU,gBAAgB,SACxC;KACgB;KACd,aAAa,gBAAgB,SACzB,kBACA,KAAA;IACN,IACA,KAAA;IACJ,GAAI,gBAAgB,UAAU,kBAAkB,SAC5C;KACkB;KAChB,eAAe,kBAAkB,SAC7B,oBACA,KAAA;IACN,IACA,KAAA;GACN,GACA,EAAE,OAAO,CACX,CAAC,CACE,KAAK,mBAAmB,CAAC,CACzB,YAAY,IAAI,IACnB,QAAQ,QAAQ,IAAI;GAGxB,MAAM,eAAe,MAAM;GAE3B,IAAI,cAAc,OAAO,MAAM,aAAa;IAE1C,MAAM,EAAE,WAAW,YAAY,aAAa,OAAO;IAClD,CAAC,WAAW,OAAO,CAAC,CAAC,SAAS,UAAU;KAEvC,YAAY,eACV,EAAE,UAAU,CAAC,YAAY,UAAU,SAAS,CAAC,EAAE,IAC9C,SAAS,mBAAmB,MAAM,KAAK,CAC1C;KAGA,YAAY,eACV;MACE,UAAU,CAAC,YAAY,iBAAiB,SAAS,CAAC;MAClD,OAAO;KACT,IACC,SAAS,mBAAmB,MAAM,KAAK,CAC1C;KAEA,YAAY,eACV,EACE,UAAU;MACR,YAAY,kBAAkB,SAAS;MACvC;MACA,MAAM;KACR,EACF,IACC,SAAS;MACR,IAAI,MAAM;OACR,MAAM,aAAa,CAAC,GAAG,IAAI;OAC3B,MAAM,QAAQ,WAAW,WACtB,cAAc,UAAU,YAAY,MAAM,OAC7C;OACA,IAAI,SAAS,GACX,WAAW,SAAS;QAClB,GAAG,WAAW;QACd,GAAG;OACL;OAEF,OAAO;MACT;KACF,CACF;IACF,CAAC;GACH;GAEA,MAAM,gBAAgB,cAAc,UAAU,CAAC;GAE/C,IAAI,yBAAyB,cAAc,QAAQ;IACjD,sBAAsB,UAAU,aAAa;IAC7C,QAAQ,KAAA,mBAAkC,aAAa;GAEzD,OAAO,IAAI,qBAAqB;IAE9B,QAAQ,KAAA,mBAAkC,aAAa;IACvD,OAAO;GACT;GAEA,MAAM,qBAAqB,MAAM;GAEjC,IAAI,oBAAoB;IAEtB,cAAc,OAAO,GAAG,GAAG,kBAAkB;IAE7C,QAAQ,KAAA,mBAAkC,aAAa;GACzD;GAEA,OAAO;EACT;EACA,SAAS;EACT,WAAW;EACX,gBAAgB,OAAO;GACrB,OAAO,KAAK,IACV,KAAK,IAAI,eAAe,KAAK,IAAI,IAAI,MAAM,MAAM,cAAc,GAC/D,WACF;EACF;EACA,MAAM,cAAc,OAAY;GAC9B,IAAI,QAAQ,IAAI,aAAa,eAC3B,QAAQ,KAAK,uBAAuB;IAAE;IAAc;GAAM,CAAC;GAE7D,IAAI,gBAAgB,GAClB,OAAO;GAET,IAAI,OAAO,SAAS,cAAc,UAChC,OAAO;GAET,OAAO;EACT;CACF,CAAC;CAEH,MAAM,qBAAqB,aACxB,UAAiB;EAChB,MAAM,eAAe,SAAS,UAAU,SAAS,SAAS,GAAG,GAAG,MAAM,EAAE;EACxE,YAAY,aAAa,cAAc,CAAC,KAAK,GAAG,EAC9C,WAAW,iBAAiB,KAAK,IAAI,EACvC,CAAC;EACD,mBAAmB,KAAK;CAC1B,GACA;EAAC;EAAa;EAAe;EAAoB;CAAQ,CAC3D;CAEA,OAAO;EACL,QAAQ,QAAQ,sBAAsB,QAAQ;EAC9C,WAAW,aAAa;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -17,14 +17,15 @@ const useTokens = (formType, search, chainId) => {
|
|
|
17
17
|
const { data: verifiedTokens, isLoading } = useQuery({
|
|
18
18
|
queryKey: [getQueryKey("tokens", keyPrefix)],
|
|
19
19
|
queryFn: async ({ signal }) => {
|
|
20
|
+
const chainTypes = [
|
|
21
|
+
ChainType.EVM,
|
|
22
|
+
ChainType.SVM,
|
|
23
|
+
ChainType.UTXO,
|
|
24
|
+
ChainType.MVM,
|
|
25
|
+
ChainType.TVM
|
|
26
|
+
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types));
|
|
20
27
|
const tokensResponse = await getTokens(sdkClient, {
|
|
21
|
-
chainTypes
|
|
22
|
-
ChainType.EVM,
|
|
23
|
-
ChainType.SVM,
|
|
24
|
-
ChainType.UTXO,
|
|
25
|
-
ChainType.MVM,
|
|
26
|
-
ChainType.TVM
|
|
27
|
-
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)),
|
|
28
|
+
chainTypes,
|
|
28
29
|
orderBy: "volumeUSD24H",
|
|
29
30
|
extended: true,
|
|
30
31
|
limit: 1e3,
|
|
@@ -46,14 +47,15 @@ const useTokens = (formType, search, chainId) => {
|
|
|
46
47
|
],
|
|
47
48
|
queryFn: async ({ queryKey, signal }) => {
|
|
48
49
|
const [, searchQuery, searchChainId] = queryKey;
|
|
50
|
+
const chainTypes = [
|
|
51
|
+
ChainType.EVM,
|
|
52
|
+
ChainType.SVM,
|
|
53
|
+
ChainType.UTXO,
|
|
54
|
+
ChainType.MVM,
|
|
55
|
+
ChainType.TVM
|
|
56
|
+
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types));
|
|
49
57
|
const tokensResponse = await getTokens(sdkClient, {
|
|
50
|
-
chainTypes
|
|
51
|
-
ChainType.EVM,
|
|
52
|
-
ChainType.SVM,
|
|
53
|
-
ChainType.UTXO,
|
|
54
|
-
ChainType.MVM,
|
|
55
|
-
ChainType.TVM
|
|
56
|
-
].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)),
|
|
58
|
+
chainTypes,
|
|
57
59
|
orderBy: "volumeUSD24H",
|
|
58
60
|
extended: true,
|
|
59
61
|
search: searchQuery,
|
|
@@ -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 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,gBAAgB;CACpB,MAAM,YAAY,aAAa;CAC/B,MAAM,EAAE,4BAA4B,wBAAwB;CAG5D,MAAM,EAAE,MAAM,gBAAgB,cAAc,SAAS;EACnD,UAAU,CAAC,YAAY,UAAU,SAAS,CAAC;EAC3C,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,gBAAgB;CACpB,MAAM,YAAY,aAAa;CAC/B,MAAM,EAAE,4BAA4B,wBAAwB;CAG5D,MAAM,EAAE,MAAM,gBAAgB,cAAc,SAAS;EACnD,UAAU,CAAC,YAAY,UAAU,SAAS,CAAC;EAC3C,SAAS,OAAO,EAAE,aAAa;GAC7B,MAAM,aAAa;IACjB,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;GACZ,CAAC,CAAC,QAAQ,cAAc,cAAc,WAAW,cAAc,KAAK,CAAC;GAErE,MAAM,iBAAyC,MAAM,UACnD,WACA;IACE;IACA,SAAS;IACT,UAAU;IACV,OAAO;IACP,aAAa;GACf,GACA,EAAE,OAAO,CACX;GAUA,OAP8B,OAAO,YACnC,OAAO,QAAQ,eAAe,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,YAAY,CAC/D,SACA,OAAO,KAAK,WAAW;IAAE,GAAG;IAAO,UAAU;GAAK,EAAE,CACtD,CAAC,CAGS;EACd;EACA;EACA,WAAW;CACb,CAAC;CAGD,MAAM,EAAE,MAAM,cAAc,WAAW,oBAAoB,SAAS;EAClE,UAAU;GAAC,YAAY,iBAAiB,SAAS;GAAG;GAAQ;EAAO;EACnE,SAAS,OAAO,EAAE,UAAU,aAAa;GACvC,MAAM,GAAG,aAAa,iBAAiB;GAKvC,MAAM,aAAa;IACjB,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;GACZ,CAAC,CAAC,QAAQ,cAAc,cAAc,WAAW,cAAc,KAAK,CAAC;GAErE,MAAM,iBAAyC,MAAM,UACnD,WACA;IACE;IACA,SAAS;IACT,UAAU;IACV,QAAQ;IACR,OAAO;IACP,aAAa;GACf,GACA,EAAE,OAAO,CACX;GAGA,IAAI,WAAW;GACf,IAAI,CAAC,UAAU;IACb,MAAM,YAAY,wBAAwB,WAAW;IACrD,IAAI,aAAa,aAAa,uBAC5B,WAAW,sBAAsB;GAErC;GAIA,IAAI,YAAY;QAEV,EADmB,eAAe,OAAO,aAAa,CAAC,EAAA,CACvC,QAAQ;KAC1B,MAAM,QAAQ,MAAM,SAAS,WAAW,UAAU,aAAa,EAC7D,OACF,CAAC;KACD,IAAI,OACF,eAAe,OAAO,YAAY,CAAC,KAAK;IAE5C;;GAWF,OAP8B,OAAO,YACnC,OAAO,QAAQ,eAAe,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,YAAY,CAC/D,SACA,OAAO,KAAK,WAAW;IAAE,GAAG;IAAO,UAAU;GAAM,EAAE,CACvD,CAAC,CAGS;EACd;EACA,SAAS,CAAC,CAAC;EACX;EACA,WAAW;CACb,CAAC;CAQD,OAAO;EACL,WANgB,cAAc;GAE9B,OAAO,oBADQ,8BAA8B,gBAAgB,YAC7B,GAAG,cAAc,cAAc,QAAQ;EACzE,GAAG;GAAC;GAAgB;GAAc;GAAc;GAAc;EAAQ,CAG5D;EACR;EACA;CACF;AACF"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
+
import { getTabVariant } from "../stores/navigationTabs/utils.js";
|
|
3
|
+
import { useNavigationTabsStore } from "../stores/navigationTabs/useNavigationTabsStore.js";
|
|
2
4
|
import { useMediaQuery } from "@mui/material";
|
|
3
5
|
//#region src/hooks/useWideVariant.ts
|
|
4
6
|
const defaultExpandableWidth = 852;
|
|
5
7
|
const useWideVariant = () => {
|
|
6
|
-
const
|
|
8
|
+
const config = useWidgetConfig();
|
|
9
|
+
const variant = getTabVariant(config, useNavigationTabsStore((store) => store.activeTab));
|
|
7
10
|
const expandableAllowed = useMediaQuery((theme) => theme.breakpoints.up(defaultExpandableWidth));
|
|
8
|
-
return variant === "wide" && expandableAllowed && !showSingleRoute;
|
|
11
|
+
return variant === "wide" && expandableAllowed && !config.showSingleRoute;
|
|
9
12
|
};
|
|
10
13
|
//#endregion
|
|
11
14
|
export { useWideVariant };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWideVariant.js","names":[],"sources":["../../../src/hooks/useWideVariant.ts"],"sourcesContent":["import type { Theme } from '@mui/material'\nimport { useMediaQuery } from '@mui/material'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\n\nconst defaultExpandableWidth = 852\n\nexport const useWideVariant = (): boolean => {\n const
|
|
1
|
+
{"version":3,"file":"useWideVariant.js","names":[],"sources":["../../../src/hooks/useWideVariant.ts"],"sourcesContent":["import type { Theme } from '@mui/material'\nimport { useMediaQuery } from '@mui/material'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useNavigationTabsStore } from '../stores/navigationTabs/useNavigationTabsStore.js'\nimport { getTabVariant } from '../stores/navigationTabs/utils.js'\n\nconst defaultExpandableWidth = 852\n\nexport const useWideVariant = (): boolean => {\n const config = useWidgetConfig()\n const activeTab = useNavigationTabsStore((store) => store.activeTab)\n // The active tab can pin its own variant (e.g. the limit tab is compact),\n // falling back to the widget config's variant when it doesn't.\n const variant = getTabVariant(config, activeTab)\n const expandableAllowed = useMediaQuery((theme: Theme) =>\n theme.breakpoints.up(defaultExpandableWidth)\n )\n return variant === 'wide' && expandableAllowed && !config.showSingleRoute\n}\n"],"mappings":";;;;;AAMA,MAAM,yBAAyB;AAE/B,MAAa,uBAAgC;CAC3C,MAAM,SAAS,gBAAgB;CAI/B,MAAM,UAAU,cAAc,QAHZ,wBAAwB,UAAU,MAAM,SAGZ,CAAC;CAC/C,MAAM,oBAAoB,eAAe,UACvC,MAAM,YAAY,GAAG,sBAAsB,CAC7C;CACA,OAAO,YAAY,UAAU,qBAAqB,CAAC,OAAO;AAC5D"}
|
package/dist/esm/i18n/en.json
CHANGED
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"options": "Options",
|
|
44
44
|
"reset": "Reset",
|
|
45
45
|
"resetSettings": "Reset settings",
|
|
46
|
+
"review": "Review",
|
|
46
47
|
"seeDetails": "See details",
|
|
47
48
|
"showAll": "Show all",
|
|
48
49
|
"startBridging": "Start bridging",
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
"amount": "Amount",
|
|
59
60
|
"bookmarkedWallets": "Bookmarked wallets",
|
|
60
61
|
"bridge": "Bridge",
|
|
62
|
+
"buy": "Buy",
|
|
61
63
|
"checkout": "Checkout",
|
|
62
64
|
"checkoutDetails": "Checkout details",
|
|
63
65
|
"deposit": "Deposit",
|
|
@@ -75,6 +77,7 @@
|
|
|
75
77
|
"refunded": "Refunded",
|
|
76
78
|
"selectChain": "Select chain",
|
|
77
79
|
"selectWallet": "Select your wallet",
|
|
80
|
+
"sell": "Sell",
|
|
78
81
|
"send": "Send",
|
|
79
82
|
"sendToWallet": "Send to wallet",
|
|
80
83
|
"settings": "Settings",
|
|
@@ -87,6 +90,14 @@
|
|
|
87
90
|
"youGet": "You get",
|
|
88
91
|
"youPay": "You pay"
|
|
89
92
|
},
|
|
93
|
+
"limitOrder": {
|
|
94
|
+
"custom": "Custom",
|
|
95
|
+
"expiresIn": "Expires in",
|
|
96
|
+
"market": "Market",
|
|
97
|
+
"partiallyFillable": "Allow partial fills",
|
|
98
|
+
"price": "Limit price",
|
|
99
|
+
"priceLabel": "When 1 {{symbol}} is worth"
|
|
100
|
+
},
|
|
90
101
|
"info": {
|
|
91
102
|
"message": {
|
|
92
103
|
"accountDeployedMessage": "Your smart account may not have the same address on other chains. Please double-check before proceeding.",
|
|
@@ -333,7 +344,18 @@
|
|
|
333
344
|
"title": "Gas price"
|
|
334
345
|
},
|
|
335
346
|
"routePriority": "Route priority",
|
|
347
|
+
"routePriorityOptions": {
|
|
348
|
+
"cheapest": {
|
|
349
|
+
"title": "Best Return",
|
|
350
|
+
"description": "Lowest network cost"
|
|
351
|
+
},
|
|
352
|
+
"fastest": {
|
|
353
|
+
"title": "Fastest",
|
|
354
|
+
"description": "Shortest execution time"
|
|
355
|
+
}
|
|
356
|
+
},
|
|
336
357
|
"slippage": "Max. slippage",
|
|
358
|
+
"slippageAutoDescription": "Optimised per route",
|
|
337
359
|
"custom": "Custom",
|
|
338
360
|
"resetSettings": "You're using custom settings that can affect the number or sorting of available routes.",
|
|
339
361
|
"hideSmallBalances": "Hide small balances"
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { defaultMaxHeight } from "./config/constants.js";
|
|
|
12
12
|
import { name, version } from "./config/version.js";
|
|
13
13
|
import { useWidgetChains } from "./hooks/useWidgetChains.js";
|
|
14
14
|
import { navigationRoutes } from "./utils/navigationRoutes.js";
|
|
15
|
-
import { ChainPinned, ChainTokenSelected, ContactSupport, FormFieldChanged, LowAddressActivityConfirmed, RouteExecutionUpdate, RouteHighValueLossUpdate, RouteSelected, SettingUpdated, TokenSearch, WidgetEvent, WidgetEvents } from "./types/events.js";
|
|
15
|
+
import { ChainPinned, ChainTokenSelected, ContactSupport, FormFieldChanged, LowAddressActivityConfirmed, NavigationTabChanged, RouteExecutionUpdate, RouteHighValueLossUpdate, RouteSelected, SettingUpdated, TokenSearch, WidgetEvent, WidgetEvents } from "./types/events.js";
|
|
16
16
|
import { WidgetEventEmitter, useWidgetEvents, widgetEvents } from "./hooks/useWidgetEvents.js";
|
|
17
17
|
import { Bookmark, BookmarkActions, BookmarkProps, BookmarkState, BookmarkStore } from "./stores/bookmarks/types.js";
|
|
18
18
|
import { useFieldActions } from "./stores/form/useFieldActions.js";
|
|
@@ -30,4 +30,4 @@ import { getPriceImpact } from "./utils/getPriceImpact.js";
|
|
|
30
30
|
import { percentFormatter } from "./utils/percentFormatter.js";
|
|
31
31
|
import { ChainId, ChainType, CoinKey } from "@lifi/sdk";
|
|
32
32
|
export type * from "@lifi/sdk";
|
|
33
|
-
export { AllowDeny, AllowDenyItems, AllowDenySet, AllowDenySetItem, AllowDenySets, Appearance, Bookmark, BookmarkActions, BookmarkProps, BookmarkState, BookmarkStore, CalculateFeeParams, ChainId, ChainPinned, ChainTokenSelected, ChainType, CoinKey, ContactSupport, CustomMode, DefaultFieldValues, DefaultUI, DefaultValues, DisabledUIConfig, ExpansionType, ExplorerUrl, ExtractValueType, FieldNames, FieldValues, FormActions, FormFieldArray, FormFieldChanged, FormFieldNames, FormFieldOptions, FormKeyHelper, FormProps, FormRef, FormRefProps, FormState, FormStoreStore, FormType, FormTypeProps, FormValueControl, FormValues, FormValuesState, GenericFormValue, HiddenUIConfig, InternalNavigationTabKey, InternalWidgetMode, ItemPrice, ItemPriceProps, App as LiFiWidget, LowAddressActivityConfirmed, ModeOptions, NFT, NFTBase, NFTBaseProps, NFTOwner, NFTProps, NavigationProps, NavigationTabKey, PoweredByType, RequiredUIConfig, ResetOptions, RouteExecutionUpdate, RouteHighValueLossUpdate, RouteLabel, RouteLabelRule, RouteSelected, SetFieldValueFunction, SetOptions, SettingUpdated, SplitMode, SplitModeOptions, SplitNavigationTabKey, ToAddress, type TokenAmount, TokenSearch, TouchedFields, ValidationActions, ValidationProps, WidgetChains, WidgetConfig, WidgetConfigPartialProps, WidgetConfigProps, WidgetContractTool, type WidgetDrawer, WidgetDrawerProps, WidgetEvent, type WidgetEventEmitter, WidgetEvents, WidgetFeeConfig, WidgetLanguages, WidgetMode, WidgetProps, WidgetProvider, WidgetSDKConfig, WidgetSkeleton, WidgetTheme, WidgetThemeComponents, WidgetTokens, WidgetVariant, WidgetWalletConfig, azureLightTheme, compactNumberFormatter, createTheme, currencyExtendedFormatter, defaultMaxHeight, formatDuration, formatInputAmount, formatSlippage, formatTokenAmount, formatTokenPrice, getPriceImpact, jumperTheme, name, navigationRoutes, palette, paletteDark, paletteLight, percentFormatter, priceToTokenAmount, usdDecimals, useFieldActions, useFieldValues, useWidgetChains, useWidgetEvents, version, watermelonLightTheme, widgetEvents, windows95Theme, wrapLongWords };
|
|
33
|
+
export { AllowDeny, AllowDenyItems, AllowDenySet, AllowDenySetItem, AllowDenySets, Appearance, Bookmark, BookmarkActions, BookmarkProps, BookmarkState, BookmarkStore, CalculateFeeParams, ChainId, ChainPinned, ChainTokenSelected, ChainType, CoinKey, ContactSupport, CustomMode, DefaultFieldValues, DefaultUI, DefaultValues, DisabledUIConfig, ExpansionType, ExplorerUrl, ExtractValueType, FieldNames, FieldValues, FormActions, FormFieldArray, FormFieldChanged, FormFieldNames, FormFieldOptions, FormKeyHelper, FormProps, FormRef, FormRefProps, FormState, FormStoreStore, FormType, FormTypeProps, FormValueControl, FormValues, FormValuesState, GenericFormValue, HiddenUIConfig, InternalNavigationTabKey, InternalWidgetMode, ItemPrice, ItemPriceProps, App as LiFiWidget, LowAddressActivityConfirmed, ModeOptions, NFT, NFTBase, NFTBaseProps, NFTOwner, NFTProps, NavigationProps, NavigationTabChanged, NavigationTabKey, PoweredByType, RequiredUIConfig, ResetOptions, RouteExecutionUpdate, RouteHighValueLossUpdate, RouteLabel, RouteLabelRule, RouteSelected, SetFieldValueFunction, SetOptions, SettingUpdated, SplitMode, SplitModeOptions, SplitNavigationTabKey, ToAddress, type TokenAmount, TokenSearch, TouchedFields, ValidationActions, ValidationProps, WidgetChains, WidgetConfig, WidgetConfigPartialProps, WidgetConfigProps, WidgetContractTool, type WidgetDrawer, WidgetDrawerProps, WidgetEvent, type WidgetEventEmitter, WidgetEvents, WidgetFeeConfig, WidgetLanguages, WidgetMode, WidgetProps, WidgetProvider, WidgetSDKConfig, WidgetSkeleton, WidgetTheme, WidgetThemeComponents, WidgetTokens, WidgetVariant, WidgetWalletConfig, azureLightTheme, compactNumberFormatter, createTheme, currencyExtendedFormatter, defaultMaxHeight, formatDuration, formatInputAmount, formatSlippage, formatTokenAmount, formatTokenPrice, getPriceImpact, jumperTheme, name, navigationRoutes, palette, paletteDark, paletteLight, percentFormatter, priceToTokenAmount, usdDecimals, useFieldActions, useFieldValues, useWidgetChains, useWidgetEvents, version, watermelonLightTheme, widgetEvents, windows95Theme, wrapLongWords };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PageContainer } from "../../components/PageContainer.js";
|
|
2
|
+
import { AmountInputCardPair } from "../../components/AmountInputCard/AmountInputCardPair.js";
|
|
3
|
+
import { LimitOrderSettings } from "../../components/LimitOrderSettings/LimitOrderSettings.js";
|
|
4
|
+
import { LimitOrderRoutes } from "../../components/Routes/LimitOrderRoutes.js";
|
|
5
|
+
import { MainPageActions } from "./MainPageActions.js";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/pages/MainPage/LimitPageContent.tsx
|
|
8
|
+
const marginSx = { marginBottom: 2 };
|
|
9
|
+
const LimitPageContent = () => {
|
|
10
|
+
return /* @__PURE__ */ jsxs(PageContainer, {
|
|
11
|
+
topGutters: true,
|
|
12
|
+
children: [
|
|
13
|
+
/* @__PURE__ */ jsx(AmountInputCardPair, { sx: marginSx }),
|
|
14
|
+
/* @__PURE__ */ jsx(LimitOrderSettings, { sx: marginSx }),
|
|
15
|
+
/* @__PURE__ */ jsx(LimitOrderRoutes, { sx: marginSx }),
|
|
16
|
+
/* @__PURE__ */ jsx(MainPageActions, {})
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { LimitPageContent };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=LimitPageContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LimitPageContent.js","names":[],"sources":["../../../../src/pages/MainPage/LimitPageContent.tsx"],"sourcesContent":["import { AmountInputCardPair } from '../../components/AmountInputCard/AmountInputCardPair.js'\nimport { LimitOrderSettings } from '../../components/LimitOrderSettings/LimitOrderSettings.js'\nimport { PageContainer } from '../../components/PageContainer.js'\nimport { LimitOrderRoutes } from '../../components/Routes/LimitOrderRoutes.js'\nimport { MainPageActions } from './MainPageActions.js'\n\nconst marginSx = { marginBottom: 2 }\n\nexport const LimitPageContent: React.FC = () => {\n return (\n <PageContainer topGutters>\n <AmountInputCardPair sx={marginSx} />\n <LimitOrderSettings sx={marginSx} />\n <LimitOrderRoutes sx={marginSx} />\n <MainPageActions />\n </PageContainer>\n )\n}\n"],"mappings":";;;;;;;AAMA,MAAM,WAAW,EAAE,cAAc,EAAE;AAEnC,MAAa,yBAAmC;CAC9C,OACE,qBAAC,eAAD;EAAe,YAAA;YAAf;GACE,oBAAC,qBAAD,EAAqB,IAAI,SAAW,CAAA;GACpC,oBAAC,oBAAD,EAAoB,IAAI,SAAW,CAAA;GACnC,oBAAC,kBAAD,EAAkB,IAAI,SAAW,CAAA;GACjC,oBAAC,iBAAD,CAAkB,CAAA;EACL;;AAEnB"}
|
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
+
import { useNavigationTabsStore } from "../../stores/navigationTabs/useNavigationTabsStore.js";
|
|
2
3
|
import { PageContainer } from "../../components/PageContainer.js";
|
|
3
4
|
import { useWideVariant } from "../../hooks/useWideVariant.js";
|
|
4
5
|
import { useHeader } from "../../hooks/useHeader.js";
|
|
5
6
|
import { AmountInput } from "../../components/AmountInput/AmountInput.js";
|
|
7
|
+
import { AmountInputCardPair } from "../../components/AmountInputCard/AmountInputCardPair.js";
|
|
6
8
|
import { ContractComponent } from "../../components/ContractComponent/ContractComponent.js";
|
|
7
9
|
import { GasRefuelMessage } from "../../components/Messages/GasRefuelMessage.js";
|
|
8
|
-
import { PoweredBy } from "../../components/PoweredBy/PoweredBy.js";
|
|
9
10
|
import { Routes } from "../../components/Routes/Routes.js";
|
|
10
11
|
import { SelectChainAndToken } from "../../components/SelectChainAndToken.js";
|
|
11
12
|
import { SendToWalletButton } from "../../components/SendToWallet/SendToWalletButton.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { advancedNavigationTabKeys } from "../../components/SettingsPanel/utils.js";
|
|
14
|
+
import { SettingsPanel } from "../../components/SettingsPanel/SettingsPanel.js";
|
|
15
|
+
import { MainPageActions } from "./MainPageActions.js";
|
|
16
|
+
import { LimitPageContent } from "./LimitPageContent.js";
|
|
17
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
17
18
|
import { useTranslation } from "react-i18next";
|
|
18
19
|
//#region src/pages/MainPage/MainPage.tsx
|
|
20
|
+
const marginSx = { marginBottom: 2 };
|
|
19
21
|
const MainPage = () => {
|
|
20
22
|
const { t } = useTranslation();
|
|
21
23
|
const wideVariant = useWideVariant();
|
|
22
|
-
const { mode, modeOptions, contractComponent, hiddenUI } = useWidgetConfig();
|
|
24
|
+
const { mode, modeOptions, contractComponent, hiddenUI, defaultUI } = useWidgetConfig();
|
|
25
|
+
const activeTab = useNavigationTabsStore((state) => state.activeTab);
|
|
23
26
|
const custom = mode === "custom";
|
|
24
|
-
const
|
|
27
|
+
const advancedMode = !!activeTab && advancedNavigationTabKeys.includes(activeTab);
|
|
28
|
+
const showSendReceiveCards = defaultUI?.layout === "cards";
|
|
29
|
+
const showAmountEntry = !custom || modeOptions?.custom?.type === "deposit";
|
|
25
30
|
const showGasRefuelMessage = !hiddenUI?.gasRefuelMessage;
|
|
26
31
|
const splitTitle = modeOptions?.split === "bridge" ? t("header.bridge") : modeOptions?.split === "swap" ? t("header.swap") : void 0;
|
|
27
|
-
useHeader(mode === "custom" ? t(`header.${modeOptions?.custom?.type ?? "checkout"}`) : mode === "refuel" ? t("header.gas") : mode === "split" && splitTitle ? splitTitle : t("header.exchange"));
|
|
28
|
-
|
|
32
|
+
useHeader(mode === "limit" ? t("header.limit") : mode === "custom" ? t(`header.${modeOptions?.custom?.type ?? "checkout"}`) : mode === "refuel" ? t("header.gas") : mode === "split" && splitTitle ? splitTitle : t("header.exchange"));
|
|
33
|
+
if (mode === "limit") return /* @__PURE__ */ jsx(LimitPageContent, {});
|
|
29
34
|
return /* @__PURE__ */ jsxs(PageContainer, {
|
|
30
35
|
topGutters: true,
|
|
31
36
|
children: [
|
|
@@ -33,23 +38,15 @@ const MainPage = () => {
|
|
|
33
38
|
sx: marginSx,
|
|
34
39
|
children: contractComponent
|
|
35
40
|
}) : null,
|
|
36
|
-
/* @__PURE__ */ jsx(SelectChainAndToken, { sx: marginSx }),
|
|
37
|
-
!custom || modeOptions?.custom?.type === "deposit" ? /* @__PURE__ */ jsx(AmountInput, {
|
|
41
|
+
showSendReceiveCards && showAmountEntry ? /* @__PURE__ */ jsx(AmountInputCardPair, { sx: marginSx }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SelectChainAndToken, { sx: marginSx }), !showSendReceiveCards && showAmountEntry ? /* @__PURE__ */ jsx(AmountInput, {
|
|
38
42
|
formType: "from",
|
|
39
43
|
sx: marginSx
|
|
40
|
-
}) : null,
|
|
44
|
+
}) : null] }),
|
|
45
|
+
advancedMode ? /* @__PURE__ */ jsx(SettingsPanel, { sx: marginSx }) : null,
|
|
41
46
|
!wideVariant ? /* @__PURE__ */ jsx(Routes, { sx: marginSx }) : null,
|
|
42
47
|
/* @__PURE__ */ jsx(SendToWalletButton, { sx: marginSx }),
|
|
43
48
|
showGasRefuelMessage ? /* @__PURE__ */ jsx(GasRefuelMessage, { sx: marginSx }) : null,
|
|
44
|
-
/* @__PURE__ */ jsx(
|
|
45
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
46
|
-
sx: {
|
|
47
|
-
display: "flex",
|
|
48
|
-
mb: showPoweredBy ? 1 : 3
|
|
49
|
-
},
|
|
50
|
-
children: [/* @__PURE__ */ jsx(ReviewButton, {}), /* @__PURE__ */ jsx(SendToWalletExpandButton, {})]
|
|
51
|
-
}),
|
|
52
|
-
showPoweredBy ? /* @__PURE__ */ jsx(PoweredBy, {}) : null
|
|
49
|
+
/* @__PURE__ */ jsx(MainPageActions, { showSendToWalletExpand: true })
|
|
53
50
|
]
|
|
54
51
|
});
|
|
55
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MainPage.js","names":[],"sources":["../../../../src/pages/MainPage/MainPage.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"MainPage.js","names":[],"sources":["../../../../src/pages/MainPage/MainPage.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport { AmountInput } from '../../components/AmountInput/AmountInput.js'\nimport { AmountInputCardPair } from '../../components/AmountInputCard/AmountInputCardPair.js'\nimport { ContractComponent } from '../../components/ContractComponent/ContractComponent.js'\nimport { GasRefuelMessage } from '../../components/Messages/GasRefuelMessage.js'\nimport { PageContainer } from '../../components/PageContainer.js'\nimport { Routes } from '../../components/Routes/Routes.js'\nimport { SelectChainAndToken } from '../../components/SelectChainAndToken.js'\nimport { SendToWalletButton } from '../../components/SendToWallet/SendToWalletButton.js'\nimport { SettingsPanel } from '../../components/SettingsPanel/SettingsPanel.js'\nimport { advancedNavigationTabKeys } from '../../components/SettingsPanel/utils.js'\nimport { useHeader } from '../../hooks/useHeader.js'\nimport { useWideVariant } from '../../hooks/useWideVariant.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useNavigationTabsStore } from '../../stores/navigationTabs/useNavigationTabsStore.js'\nimport { LimitPageContent } from './LimitPageContent.js'\nimport { MainPageActions } from './MainPageActions.js'\n\nconst marginSx = { marginBottom: 2 }\n\nexport const MainPage: React.FC = () => {\n const { t } = useTranslation()\n const wideVariant = useWideVariant()\n const { mode, modeOptions, contractComponent, hiddenUI, defaultUI } =\n useWidgetConfig()\n const activeTab = useNavigationTabsStore((state) => state.activeTab)\n\n const custom = mode === 'custom'\n // Surface the settings panel on the main page for advanced navigation tabs.\n const advancedMode =\n !!activeTab && advancedNavigationTabKeys.includes(activeTab)\n const showSendReceiveCards = defaultUI?.layout === 'cards'\n // Custom non-deposit contract flows have no amount entry — they keep the\n // chain/token selectors only, in both layouts.\n const showAmountEntry = !custom || modeOptions?.custom?.type === 'deposit'\n const showGasRefuelMessage = !hiddenUI?.gasRefuelMessage\n\n const splitTitle =\n modeOptions?.split === 'bridge'\n ? t('header.bridge')\n : modeOptions?.split === 'swap'\n ? t('header.swap')\n : undefined\n const title =\n mode === 'limit'\n ? t('header.limit')\n : mode === 'custom'\n ? t(`header.${modeOptions?.custom?.type ?? 'checkout'}`)\n : mode === 'refuel'\n ? t('header.gas')\n : mode === 'split' && splitTitle\n ? splitTitle\n : t('header.exchange')\n\n useHeader(title)\n\n if (mode === 'limit') {\n return <LimitPageContent />\n }\n\n return (\n <PageContainer topGutters>\n {custom ? (\n <ContractComponent sx={marginSx}>{contractComponent}</ContractComponent>\n ) : null}\n {showSendReceiveCards && showAmountEntry ? (\n <AmountInputCardPair sx={marginSx} />\n ) : (\n <>\n <SelectChainAndToken sx={marginSx} />\n {!showSendReceiveCards && showAmountEntry ? (\n <AmountInput formType=\"from\" sx={marginSx} />\n ) : null}\n </>\n )}\n {advancedMode ? <SettingsPanel sx={marginSx} /> : null}\n {!wideVariant ? <Routes sx={marginSx} /> : null}\n <SendToWalletButton sx={marginSx} />\n {showGasRefuelMessage ? <GasRefuelMessage sx={marginSx} /> : null}\n <MainPageActions showSendToWalletExpand />\n </PageContainer>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAM,WAAW,EAAE,cAAc,EAAE;AAEnC,MAAa,iBAA2B;CACtC,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,cAAc,eAAe;CACnC,MAAM,EAAE,MAAM,aAAa,mBAAmB,UAAU,cACtD,gBAAgB;CAClB,MAAM,YAAY,wBAAwB,UAAU,MAAM,SAAS;CAEnE,MAAM,SAAS,SAAS;CAExB,MAAM,eACJ,CAAC,CAAC,aAAa,0BAA0B,SAAS,SAAS;CAC7D,MAAM,uBAAuB,WAAW,WAAW;CAGnD,MAAM,kBAAkB,CAAC,UAAU,aAAa,QAAQ,SAAS;CACjE,MAAM,uBAAuB,CAAC,UAAU;CAExC,MAAM,aACJ,aAAa,UAAU,WACnB,EAAE,eAAe,IACjB,aAAa,UAAU,SACrB,EAAE,aAAa,IACf,KAAA;CAYR,UAVE,SAAS,UACL,EAAE,cAAc,IAChB,SAAS,WACP,EAAE,UAAU,aAAa,QAAQ,QAAQ,YAAY,IACrD,SAAS,WACP,EAAE,YAAY,IACd,SAAS,WAAW,aAClB,aACA,EAAE,iBAAiB,CAEhB;CAEf,IAAI,SAAS,SACX,OAAO,oBAAC,kBAAD,CAAmB,CAAA;CAG5B,OACE,qBAAC,eAAD;EAAe,YAAA;YAAf;GACG,SACC,oBAAC,mBAAD;IAAmB,IAAI;cAAW;GAAqC,CAAA,IACrE;GACH,wBAAwB,kBACvB,oBAAC,qBAAD,EAAqB,IAAI,SAAW,CAAA,IAEpC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,qBAAD,EAAqB,IAAI,SAAW,CAAA,GACnC,CAAC,wBAAwB,kBACxB,oBAAC,aAAD;IAAa,UAAS;IAAO,IAAI;GAAW,CAAA,IAC1C,IACJ,EAAA,CAAA;GAEH,eAAe,oBAAC,eAAD,EAAe,IAAI,SAAW,CAAA,IAAI;GACjD,CAAC,cAAc,oBAAC,QAAD,EAAQ,IAAI,SAAW,CAAA,IAAI;GAC3C,oBAAC,oBAAD,EAAoB,IAAI,SAAW,CAAA;GAClC,uBAAuB,oBAAC,kBAAD,EAAkB,IAAI,SAAW,CAAA,IAAI;GAC7D,oBAAC,iBAAD,EAAiB,wBAAA,KAAwB,CAAA;EAC5B;;AAEnB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
2
|
+
import { PoweredBy } from "../../components/PoweredBy/PoweredBy.js";
|
|
3
|
+
import { SendToWalletExpandButton } from "../../components/SendToWallet/SendToWalletExpandButton.js";
|
|
4
|
+
import { MainWarningMessages } from "./MainWarningMessages.js";
|
|
5
|
+
import { ReviewButton } from "./ReviewButton.js";
|
|
6
|
+
import { Box } from "@mui/material";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/pages/MainPage/MainPageActions.tsx
|
|
9
|
+
const marginSx = { marginBottom: 2 };
|
|
10
|
+
const MainPageActions = ({ showSendToWalletExpand }) => {
|
|
11
|
+
const { hiddenUI } = useWidgetConfig();
|
|
12
|
+
const showPoweredBy = !hiddenUI?.poweredBy;
|
|
13
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14
|
+
/* @__PURE__ */ jsx(MainWarningMessages, { sx: marginSx }),
|
|
15
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
16
|
+
sx: {
|
|
17
|
+
display: "flex",
|
|
18
|
+
mb: showPoweredBy ? 1 : 3
|
|
19
|
+
},
|
|
20
|
+
children: [/* @__PURE__ */ jsx(ReviewButton, {}), showSendToWalletExpand ? /* @__PURE__ */ jsx(SendToWalletExpandButton, {}) : null]
|
|
21
|
+
}),
|
|
22
|
+
showPoweredBy ? /* @__PURE__ */ jsx(PoweredBy, {}) : null
|
|
23
|
+
] });
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { MainPageActions };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=MainPageActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MainPageActions.js","names":[],"sources":["../../../../src/pages/MainPage/MainPageActions.tsx"],"sourcesContent":["import { Box } from '@mui/material'\nimport { PoweredBy } from '../../components/PoweredBy/PoweredBy.js'\nimport { SendToWalletExpandButton } from '../../components/SendToWallet/SendToWalletExpandButton.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { MainWarningMessages } from './MainWarningMessages.js'\nimport { ReviewButton } from './ReviewButton.js'\n\ninterface MainPageActionsProps {\n showSendToWalletExpand?: boolean\n}\n\nconst marginSx = { marginBottom: 2 }\n\nexport const MainPageActions: React.FC<MainPageActionsProps> = ({\n showSendToWalletExpand,\n}) => {\n const { hiddenUI } = useWidgetConfig()\n const showPoweredBy = !hiddenUI?.poweredBy\n\n return (\n <>\n <MainWarningMessages sx={marginSx} />\n <Box\n sx={{\n display: 'flex',\n mb: showPoweredBy ? 1 : 3,\n }}\n >\n <ReviewButton />\n {showSendToWalletExpand ? <SendToWalletExpandButton /> : null}\n </Box>\n {showPoweredBy ? <PoweredBy /> : null}\n </>\n )\n}\n"],"mappings":";;;;;;;;AAWA,MAAM,WAAW,EAAE,cAAc,EAAE;AAEnC,MAAa,mBAAmD,EAC9D,6BACI;CACJ,MAAM,EAAE,aAAa,gBAAgB;CACrC,MAAM,gBAAgB,CAAC,UAAU;CAEjC,OACE,qBAAA,UAAA,EAAA,UAAA;EACE,oBAAC,qBAAD,EAAqB,IAAI,SAAW,CAAA;EACpC,qBAAC,KAAD;GACE,IAAI;IACF,SAAS;IACT,IAAI,gBAAgB,IAAI;GAC1B;aAJF,CAME,oBAAC,cAAD,CAAe,CAAA,GACd,yBAAyB,oBAAC,0BAAD,CAA2B,CAAA,IAAI,IACtD;;EACJ,gBAAgB,oBAAC,WAAD,CAAY,CAAA,IAAI;CACjC,EAAA,CAAA;AAEN"}
|