@lifi/widget 4.1.0 → 4.3.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/useFilteredByTokenBalances.js +4 -1
- package/dist/esm/hooks/useFilteredByTokenBalances.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 +10 -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/dist/esm/utils/token.js +38 -3
- package/dist/esm/utils/token.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/useFilteredByTokenBalances.ts +7 -2
- 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 +10 -0
- package/src/utils/format.ts +6 -2
- package/src/utils/limitOrder.ts +88 -0
- package/src/utils/navigationRoutes.ts +6 -0
- package/src/utils/token.ts +71 -20
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { useCallback, useMemo } from 'react'
|
|
|
18
18
|
import { useSDKClient } from '../providers/SDKClientProvider.js'
|
|
19
19
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
20
20
|
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
21
|
+
import { useNavigationTabsStore } from '../stores/navigationTabs/useNavigationTabsStore.js'
|
|
21
22
|
import { useIntermediateRoutesStore } from '../stores/routes/useIntermediateRoutesStore.js'
|
|
22
23
|
import { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js'
|
|
23
24
|
import { defaultSlippage } from '../stores/settings/createSettingsStore.js'
|
|
@@ -70,6 +71,10 @@ export const useRoutes = ({
|
|
|
70
71
|
const queryClient = useQueryClient()
|
|
71
72
|
const emitter = useWidgetEvents()
|
|
72
73
|
const swapOnly = useSwapOnly()
|
|
74
|
+
const isPrivate = useNavigationTabsStore(
|
|
75
|
+
(state) => state.activeTab === 'private'
|
|
76
|
+
)
|
|
77
|
+
|
|
73
78
|
const {
|
|
74
79
|
disabledBridges,
|
|
75
80
|
disabledExchanges,
|
|
@@ -88,11 +93,12 @@ export const useRoutes = ({
|
|
|
88
93
|
'slippage',
|
|
89
94
|
])
|
|
90
95
|
const [fromTokenAmount] = useDebouncedWatch(500, 'fromAmount')
|
|
96
|
+
// Debounce toAmount like fromAmount to avoid a request per keystroke
|
|
97
|
+
const [toTokenAmount] = useDebouncedWatch(500, 'toAmount')
|
|
91
98
|
const [
|
|
92
99
|
fromChainId,
|
|
93
100
|
fromTokenAddress,
|
|
94
101
|
toAddress,
|
|
95
|
-
toTokenAmount,
|
|
96
102
|
toChainId,
|
|
97
103
|
toTokenAddress,
|
|
98
104
|
contractCalls,
|
|
@@ -100,11 +106,14 @@ export const useRoutes = ({
|
|
|
100
106
|
'fromChain',
|
|
101
107
|
'fromToken',
|
|
102
108
|
'toAddress',
|
|
103
|
-
'toAmount',
|
|
104
109
|
'toChain',
|
|
105
110
|
'toToken',
|
|
106
111
|
'contractCalls'
|
|
107
112
|
)
|
|
113
|
+
const [validUntilDuration, partiallyFillable] = useFieldValues(
|
|
114
|
+
'validUntil',
|
|
115
|
+
'partiallyFillable'
|
|
116
|
+
)
|
|
108
117
|
const { token: fromToken } = useToken(fromChainId, fromTokenAddress)
|
|
109
118
|
const { token: toToken } = useToken(toChainId, toTokenAddress)
|
|
110
119
|
const { chain: fromChain } = useChain(fromChainId)
|
|
@@ -117,7 +126,15 @@ export const useRoutes = ({
|
|
|
117
126
|
const { isBatchingSupported, isBatchingSupportedLoading } =
|
|
118
127
|
useIsBatchingSupported(fromChain, account.address)
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
// In limit mode toAmount is the user's limit target, derived from the sell
|
|
130
|
+
// amount and limit price. It's keyed and sent to the backend so changing the
|
|
131
|
+
// limit fetches a fresh quote. The receive card is read-only (it displays the
|
|
132
|
+
// quote and never writes toAmount back), so keying on it can't loop. Both a
|
|
133
|
+
// sell amount and a limit price (→ toAmount) are required before fetching.
|
|
134
|
+
const hasAmount =
|
|
135
|
+
mode === 'limit'
|
|
136
|
+
? Number(fromTokenAmount) > 0 && Number(toTokenAmount) > 0
|
|
137
|
+
: Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0
|
|
121
138
|
|
|
122
139
|
const contractCallQuoteEnabled: boolean =
|
|
123
140
|
mode === 'custom' ? Boolean(contractCalls && account.address) : true
|
|
@@ -169,6 +186,8 @@ export const useRoutes = ({
|
|
|
169
186
|
toChain?.id as number,
|
|
170
187
|
toToken?.address as string,
|
|
171
188
|
toTokenAmount,
|
|
189
|
+
validUntilDuration,
|
|
190
|
+
partiallyFillable,
|
|
172
191
|
contractCalls,
|
|
173
192
|
slippage,
|
|
174
193
|
swapOnly,
|
|
@@ -184,6 +203,7 @@ export const useRoutes = ({
|
|
|
184
203
|
feeConfig?.fee,
|
|
185
204
|
disableMessageSigning,
|
|
186
205
|
!!isBatchingSupported,
|
|
206
|
+
isPrivate,
|
|
187
207
|
observableRoute?.id,
|
|
188
208
|
] as const,
|
|
189
209
|
[
|
|
@@ -196,6 +216,8 @@ export const useRoutes = ({
|
|
|
196
216
|
toChain?.id,
|
|
197
217
|
toToken?.address,
|
|
198
218
|
toTokenAmount,
|
|
219
|
+
validUntilDuration,
|
|
220
|
+
partiallyFillable,
|
|
199
221
|
contractCalls,
|
|
200
222
|
slippage,
|
|
201
223
|
swapOnly,
|
|
@@ -212,6 +234,7 @@ export const useRoutes = ({
|
|
|
212
234
|
feeConfig?.fee,
|
|
213
235
|
disableMessageSigning,
|
|
214
236
|
isBatchingSupported,
|
|
237
|
+
isPrivate,
|
|
215
238
|
observableRoute?.id,
|
|
216
239
|
]
|
|
217
240
|
)
|
|
@@ -233,6 +256,8 @@ export const useRoutes = ({
|
|
|
233
256
|
toChainId,
|
|
234
257
|
toTokenAddress,
|
|
235
258
|
toTokenAmount,
|
|
259
|
+
validUntilDuration,
|
|
260
|
+
partiallyFillable,
|
|
236
261
|
contractCalls,
|
|
237
262
|
slippage = defaultSlippage,
|
|
238
263
|
swapOnly,
|
|
@@ -248,13 +273,16 @@ export const useRoutes = ({
|
|
|
248
273
|
configuredFee,
|
|
249
274
|
disableMessageSigning,
|
|
250
275
|
isBatchingSupported,
|
|
276
|
+
isPrivate,
|
|
251
277
|
// _observableRouteId must be the last element in the query key
|
|
252
278
|
_observableRouteId,
|
|
253
279
|
],
|
|
254
280
|
signal,
|
|
255
281
|
}) => {
|
|
256
282
|
const fromAmount = parseUnits(fromTokenAmount, fromToken!.decimals)
|
|
257
|
-
const toAmount =
|
|
283
|
+
const toAmount = toTokenAmount
|
|
284
|
+
? parseUnits(toTokenAmount, toToken!.decimals)
|
|
285
|
+
: undefined
|
|
258
286
|
const formattedSlippage = slippage
|
|
259
287
|
? Number.parseFloat(slippage) / 100
|
|
260
288
|
: defaultSlippage
|
|
@@ -360,6 +388,8 @@ export const useRoutes = ({
|
|
|
360
388
|
const shouldUseMainRoutes =
|
|
361
389
|
!observableRoute || !isObservableRelayerRoute
|
|
362
390
|
const shouldUseRelayerQuote =
|
|
391
|
+
// Relayer quotes don't support limit-order params
|
|
392
|
+
mode !== 'limit' &&
|
|
363
393
|
fromAddress &&
|
|
364
394
|
fromChain?.chainType === ChainType.EVM &&
|
|
365
395
|
fromChain.permit2 &&
|
|
@@ -370,6 +400,15 @@ export const useRoutes = ({
|
|
|
370
400
|
!isBatchingSupported &&
|
|
371
401
|
(!observableRoute || isObservableRelayerRoute)
|
|
372
402
|
|
|
403
|
+
const limitOrderRouteParams =
|
|
404
|
+
mode === 'limit'
|
|
405
|
+
? {
|
|
406
|
+
toAmount: toAmount?.toString(),
|
|
407
|
+
validUntil: Math.floor(Date.now() / 1000) + validUntilDuration,
|
|
408
|
+
partiallyFillable: partiallyFillable,
|
|
409
|
+
}
|
|
410
|
+
: undefined
|
|
411
|
+
|
|
373
412
|
const mainRoutesPromise = shouldUseMainRoutes
|
|
374
413
|
? getRoutes(
|
|
375
414
|
sdkClient,
|
|
@@ -385,6 +424,7 @@ export const useRoutes = ({
|
|
|
385
424
|
enabledRefuel && gasRecommendationFromAmount
|
|
386
425
|
? gasRecommendationFromAmount
|
|
387
426
|
: undefined,
|
|
427
|
+
...limitOrderRouteParams,
|
|
388
428
|
options: {
|
|
389
429
|
allowSwitchChain:
|
|
390
430
|
mode === 'refuel' ? false : allowSwitchChain,
|
|
@@ -410,6 +450,7 @@ export const useRoutes = ({
|
|
|
410
450
|
slippage: formattedSlippage,
|
|
411
451
|
fee: calculatedFee || configuredFee,
|
|
412
452
|
executionType: disableMessageSigning ? 'transaction' : 'all',
|
|
453
|
+
...(isPrivate && { private: true }),
|
|
413
454
|
},
|
|
414
455
|
},
|
|
415
456
|
{ signal }
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { Theme } from '@mui/material'
|
|
2
2
|
import { useMediaQuery } from '@mui/material'
|
|
3
3
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
4
|
+
import { useNavigationTabsStore } from '../stores/navigationTabs/useNavigationTabsStore.js'
|
|
5
|
+
import { getTabVariant } from '../stores/navigationTabs/utils.js'
|
|
4
6
|
|
|
5
7
|
const defaultExpandableWidth = 852
|
|
6
8
|
|
|
7
9
|
export const useWideVariant = (): boolean => {
|
|
8
|
-
const
|
|
10
|
+
const config = useWidgetConfig()
|
|
11
|
+
const activeTab = useNavigationTabsStore((store) => store.activeTab)
|
|
12
|
+
// The active tab can pin its own variant (e.g. the limit tab is compact),
|
|
13
|
+
// falling back to the widget config's variant when it doesn't.
|
|
14
|
+
const variant = getTabVariant(config, activeTab)
|
|
9
15
|
const expandableAllowed = useMediaQuery((theme: Theme) =>
|
|
10
16
|
theme.breakpoints.up(defaultExpandableWidth)
|
|
11
17
|
)
|
|
12
|
-
return variant === 'wide' && expandableAllowed && !showSingleRoute
|
|
18
|
+
return variant === 'wide' && expandableAllowed && !config.showSingleRoute
|
|
13
19
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AmountInputCardPair } from '../../components/AmountInputCard/AmountInputCardPair.js'
|
|
2
|
+
import { LimitOrderSettings } from '../../components/LimitOrderSettings/LimitOrderSettings.js'
|
|
3
|
+
import { PageContainer } from '../../components/PageContainer.js'
|
|
4
|
+
import { LimitOrderRoutes } from '../../components/Routes/LimitOrderRoutes.js'
|
|
5
|
+
import { MainPageActions } from './MainPageActions.js'
|
|
6
|
+
|
|
7
|
+
const marginSx = { marginBottom: 2 }
|
|
8
|
+
|
|
9
|
+
export const LimitPageContent: React.FC = () => {
|
|
10
|
+
return (
|
|
11
|
+
<PageContainer topGutters>
|
|
12
|
+
<AmountInputCardPair sx={marginSx} />
|
|
13
|
+
<LimitOrderSettings sx={marginSx} />
|
|
14
|
+
<LimitOrderRoutes sx={marginSx} />
|
|
15
|
+
<MainPageActions />
|
|
16
|
+
</PageContainer>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import { Box } from '@mui/material'
|
|
2
1
|
import { useTranslation } from 'react-i18next'
|
|
3
2
|
import { AmountInput } from '../../components/AmountInput/AmountInput.js'
|
|
3
|
+
import { AmountInputCardPair } from '../../components/AmountInputCard/AmountInputCardPair.js'
|
|
4
4
|
import { ContractComponent } from '../../components/ContractComponent/ContractComponent.js'
|
|
5
5
|
import { GasRefuelMessage } from '../../components/Messages/GasRefuelMessage.js'
|
|
6
6
|
import { PageContainer } from '../../components/PageContainer.js'
|
|
7
|
-
import { PoweredBy } from '../../components/PoweredBy/PoweredBy.js'
|
|
8
7
|
import { Routes } from '../../components/Routes/Routes.js'
|
|
9
8
|
import { SelectChainAndToken } from '../../components/SelectChainAndToken.js'
|
|
10
9
|
import { SendToWalletButton } from '../../components/SendToWallet/SendToWalletButton.js'
|
|
11
|
-
import {
|
|
10
|
+
import { SettingsPanel } from '../../components/SettingsPanel/SettingsPanel.js'
|
|
11
|
+
import { advancedNavigationTabKeys } from '../../components/SettingsPanel/utils.js'
|
|
12
12
|
import { useHeader } from '../../hooks/useHeader.js'
|
|
13
13
|
import { useWideVariant } from '../../hooks/useWideVariant.js'
|
|
14
14
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { useNavigationTabsStore } from '../../stores/navigationTabs/useNavigationTabsStore.js'
|
|
16
|
+
import { LimitPageContent } from './LimitPageContent.js'
|
|
17
|
+
import { MainPageActions } from './MainPageActions.js'
|
|
18
|
+
|
|
19
|
+
const marginSx = { marginBottom: 2 }
|
|
17
20
|
|
|
18
21
|
export const MainPage: React.FC = () => {
|
|
19
22
|
const { t } = useTranslation()
|
|
20
23
|
const wideVariant = useWideVariant()
|
|
21
|
-
const { mode, modeOptions, contractComponent, hiddenUI } =
|
|
24
|
+
const { mode, modeOptions, contractComponent, hiddenUI, defaultUI } =
|
|
25
|
+
useWidgetConfig()
|
|
26
|
+
const activeTab = useNavigationTabsStore((state) => state.activeTab)
|
|
27
|
+
|
|
22
28
|
const custom = mode === 'custom'
|
|
23
|
-
|
|
29
|
+
// Surface the settings panel on the main page for advanced navigation tabs.
|
|
30
|
+
const advancedMode =
|
|
31
|
+
!!activeTab && advancedNavigationTabKeys.includes(activeTab)
|
|
32
|
+
const showSendReceiveCards = defaultUI?.layout === 'cards'
|
|
33
|
+
// Custom non-deposit contract flows have no amount entry — they keep the
|
|
34
|
+
// chain/token selectors only, in both layouts.
|
|
35
|
+
const showAmountEntry = !custom || modeOptions?.custom?.type === 'deposit'
|
|
24
36
|
const showGasRefuelMessage = !hiddenUI?.gasRefuelMessage
|
|
25
37
|
|
|
26
38
|
const splitTitle =
|
|
@@ -30,41 +42,42 @@ export const MainPage: React.FC = () => {
|
|
|
30
42
|
? t('header.swap')
|
|
31
43
|
: undefined
|
|
32
44
|
const title =
|
|
33
|
-
mode === '
|
|
34
|
-
? t(
|
|
35
|
-
: mode === '
|
|
36
|
-
? t(
|
|
37
|
-
: mode === '
|
|
38
|
-
?
|
|
39
|
-
:
|
|
45
|
+
mode === 'limit'
|
|
46
|
+
? t('header.limit')
|
|
47
|
+
: mode === 'custom'
|
|
48
|
+
? t(`header.${modeOptions?.custom?.type ?? 'checkout'}`)
|
|
49
|
+
: mode === 'refuel'
|
|
50
|
+
? t('header.gas')
|
|
51
|
+
: mode === 'split' && splitTitle
|
|
52
|
+
? splitTitle
|
|
53
|
+
: t('header.exchange')
|
|
40
54
|
|
|
41
55
|
useHeader(title)
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
if (mode === 'limit') {
|
|
58
|
+
return <LimitPageContent />
|
|
59
|
+
}
|
|
44
60
|
|
|
45
61
|
return (
|
|
46
62
|
<PageContainer topGutters>
|
|
47
63
|
{custom ? (
|
|
48
64
|
<ContractComponent sx={marginSx}>{contractComponent}</ContractComponent>
|
|
49
65
|
) : null}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
{showSendReceiveCards && showAmountEntry ? (
|
|
67
|
+
<AmountInputCardPair sx={marginSx} />
|
|
68
|
+
) : (
|
|
69
|
+
<>
|
|
70
|
+
<SelectChainAndToken sx={marginSx} />
|
|
71
|
+
{!showSendReceiveCards && showAmountEntry ? (
|
|
72
|
+
<AmountInput formType="from" sx={marginSx} />
|
|
73
|
+
) : null}
|
|
74
|
+
</>
|
|
75
|
+
)}
|
|
76
|
+
{advancedMode ? <SettingsPanel sx={marginSx} /> : null}
|
|
54
77
|
{!wideVariant ? <Routes sx={marginSx} /> : null}
|
|
55
78
|
<SendToWalletButton sx={marginSx} />
|
|
56
79
|
{showGasRefuelMessage ? <GasRefuelMessage sx={marginSx} /> : null}
|
|
57
|
-
<
|
|
58
|
-
<Box
|
|
59
|
-
sx={{
|
|
60
|
-
display: 'flex',
|
|
61
|
-
mb: showPoweredBy ? 1 : 3,
|
|
62
|
-
}}
|
|
63
|
-
>
|
|
64
|
-
<ReviewButton />
|
|
65
|
-
<SendToWalletExpandButton />
|
|
66
|
-
</Box>
|
|
67
|
-
{showPoweredBy ? <PoweredBy /> : null}
|
|
80
|
+
<MainPageActions showSendToWalletExpand />
|
|
68
81
|
</PageContainer>
|
|
69
82
|
)
|
|
70
83
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Box } from '@mui/material'
|
|
2
|
+
import { PoweredBy } from '../../components/PoweredBy/PoweredBy.js'
|
|
3
|
+
import { SendToWalletExpandButton } from '../../components/SendToWallet/SendToWalletExpandButton.js'
|
|
4
|
+
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
5
|
+
import { MainWarningMessages } from './MainWarningMessages.js'
|
|
6
|
+
import { ReviewButton } from './ReviewButton.js'
|
|
7
|
+
|
|
8
|
+
interface MainPageActionsProps {
|
|
9
|
+
showSendToWalletExpand?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const marginSx = { marginBottom: 2 }
|
|
13
|
+
|
|
14
|
+
export const MainPageActions: React.FC<MainPageActionsProps> = ({
|
|
15
|
+
showSendToWalletExpand,
|
|
16
|
+
}) => {
|
|
17
|
+
const { hiddenUI } = useWidgetConfig()
|
|
18
|
+
const showPoweredBy = !hiddenUI?.poweredBy
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<MainWarningMessages sx={marginSx} />
|
|
23
|
+
<Box
|
|
24
|
+
sx={{
|
|
25
|
+
display: 'flex',
|
|
26
|
+
mb: showPoweredBy ? 1 : 3,
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
<ReviewButton />
|
|
30
|
+
{showSendToWalletExpand ? <SendToWalletExpandButton /> : null}
|
|
31
|
+
</Box>
|
|
32
|
+
{showPoweredBy ? <PoweredBy /> : null}
|
|
33
|
+
</>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -5,6 +5,7 @@ import { useRoutes } from '../../hooks/useRoutes.js'
|
|
|
5
5
|
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
|
|
6
6
|
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
7
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
8
|
+
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
8
9
|
import { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'
|
|
9
10
|
import { WidgetEvent } from '../../types/events.js'
|
|
10
11
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
@@ -17,8 +18,15 @@ export const ReviewButton: React.FC = () => {
|
|
|
17
18
|
const splitState = useSplitMode()
|
|
18
19
|
const { toAddress, requiredToAddress } = useToAddressRequirements()
|
|
19
20
|
const { routes, setReviewableRoute } = useRoutes()
|
|
21
|
+
const [selectedRouteId] = useFieldValues('selectedRouteId')
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
// The provider pick only applies in limit mode (it's the only flow that sets
|
|
24
|
+
// it). Honoring it in other modes would be wrong, since provider/tool keys
|
|
25
|
+
// can collide across modes. Everywhere else, fall back to the best route.
|
|
26
|
+
const currentRoute =
|
|
27
|
+
(mode === 'limit'
|
|
28
|
+
? routes?.find((route) => route.id === selectedRouteId)
|
|
29
|
+
: undefined) ?? routes?.[0]
|
|
22
30
|
|
|
23
31
|
const handleClick = async () => {
|
|
24
32
|
if (!currentRoute) {
|
|
@@ -43,6 +51,8 @@ export const ReviewButton: React.FC = () => {
|
|
|
43
51
|
return t(`button.${modeOptions?.custom?.type ?? 'checkout'}Review`)
|
|
44
52
|
case 'refuel':
|
|
45
53
|
return t('button.getGas')
|
|
54
|
+
case 'limit':
|
|
55
|
+
return t('button.review')
|
|
46
56
|
default: {
|
|
47
57
|
const transactionType =
|
|
48
58
|
currentRoute.fromChainId === currentRoute.toChainId
|
|
@@ -59,6 +69,8 @@ export const ReviewButton: React.FC = () => {
|
|
|
59
69
|
: t('button.buy')
|
|
60
70
|
case 'refuel':
|
|
61
71
|
return t('button.getGas')
|
|
72
|
+
case 'limit':
|
|
73
|
+
return t('button.review')
|
|
62
74
|
case 'split':
|
|
63
75
|
if (splitState) {
|
|
64
76
|
return t(`button.${splitState}`)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Order } from '@lifi/sdk'
|
|
2
|
+
import Check from '@mui/icons-material/Check'
|
|
3
|
+
import { List } from '@mui/material'
|
|
4
|
+
import { useRef } from 'react'
|
|
5
|
+
import { useTranslation } from 'react-i18next'
|
|
6
|
+
import { ListItemText } from '../components/ListItemText.js'
|
|
7
|
+
import { PageContainer } from '../components/PageContainer.js'
|
|
8
|
+
import { SettingsListItemButton } from '../components/SettingsListItemButton.js'
|
|
9
|
+
import { useHeader } from '../hooks/useHeader.js'
|
|
10
|
+
import { useListHeight } from '../hooks/useListHeight.js'
|
|
11
|
+
import { useSettings } from '../stores/settings/useSettings.js'
|
|
12
|
+
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
13
|
+
|
|
14
|
+
const routePriorities: Order[] = ['CHEAPEST', 'FASTEST']
|
|
15
|
+
|
|
16
|
+
export const RoutePriorityPage: React.FC = () => {
|
|
17
|
+
const { t } = useTranslation()
|
|
18
|
+
const { setValue } = useSettingsActions()
|
|
19
|
+
const { routePriority } = useSettings(['routePriority'])
|
|
20
|
+
const listParentRef = useRef<HTMLUListElement | null>(null)
|
|
21
|
+
const { listHeight } = useListHeight({ listParentRef })
|
|
22
|
+
|
|
23
|
+
useHeader(t('settings.routePriority'))
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<PageContainer disableGutters>
|
|
27
|
+
<List
|
|
28
|
+
className="long-list"
|
|
29
|
+
ref={listParentRef}
|
|
30
|
+
style={{ height: listHeight, overflow: 'auto' }}
|
|
31
|
+
sx={{
|
|
32
|
+
padding: 1.5,
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{routePriorities.map((priority) => {
|
|
36
|
+
const key = priority.toLowerCase()
|
|
37
|
+
return (
|
|
38
|
+
<SettingsListItemButton
|
|
39
|
+
key={priority}
|
|
40
|
+
onClick={() => setValue('routePriority', priority)}
|
|
41
|
+
>
|
|
42
|
+
<ListItemText
|
|
43
|
+
primary={t(`settings.routePriorityOptions.${key}.title` as any)}
|
|
44
|
+
secondary={t(
|
|
45
|
+
`settings.routePriorityOptions.${key}.description` as any
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
{routePriority === priority && <Check color="primary" />}
|
|
49
|
+
</SettingsListItemButton>
|
|
50
|
+
)
|
|
51
|
+
})}
|
|
52
|
+
</List>
|
|
53
|
+
</PageContainer>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
@@ -1,57 +1,33 @@
|
|
|
1
|
-
import type { Order } from '@lifi/sdk'
|
|
2
1
|
import Route from '@mui/icons-material/Route'
|
|
2
|
+
import { useNavigate } from '@tanstack/react-router'
|
|
3
3
|
import { useTranslation } from 'react-i18next'
|
|
4
|
-
import {
|
|
4
|
+
import { CardButton } from '../../components/Card/CardButton.js'
|
|
5
5
|
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js'
|
|
6
6
|
import { useSettings } from '../../stores/settings/useSettings.js'
|
|
7
|
-
import {
|
|
7
|
+
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
8
8
|
import { BadgedValue } from './SettingsCard/BadgedValue.js'
|
|
9
|
-
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js'
|
|
10
|
-
|
|
11
|
-
const Priorities: Order[] = ['CHEAPEST', 'FASTEST']
|
|
12
9
|
|
|
13
10
|
export const RoutePrioritySettings: React.FC = () => {
|
|
14
11
|
const { t } = useTranslation()
|
|
15
|
-
const
|
|
12
|
+
const navigate = useNavigate()
|
|
16
13
|
const { isRoutePriorityChanged } = useSettingMonitor()
|
|
17
14
|
const { routePriority } = useSettings(['routePriority'])
|
|
18
|
-
const currentRoutePriority = routePriority ?? ''
|
|
19
15
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
routePriority: Order
|
|
23
|
-
) => {
|
|
24
|
-
setValue('routePriority', routePriority)
|
|
16
|
+
const handleClick = () => {
|
|
17
|
+
navigate({ to: navigationRoutes.routePriority })
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
<BadgedValue badgeColor="info" showBadge={isRoutePriorityChanged}>
|
|
31
|
-
{t(`main.tags.${currentRoutePriority.toLowerCase()}` as any)}
|
|
32
|
-
</BadgedValue>
|
|
33
|
-
}
|
|
21
|
+
<CardButton
|
|
22
|
+
onClick={handleClick}
|
|
34
23
|
icon={<Route />}
|
|
35
24
|
title={t('settings.routePriority')}
|
|
36
25
|
>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
>
|
|
44
|
-
{Priorities.map((priority) => {
|
|
45
|
-
return (
|
|
46
|
-
<Tab
|
|
47
|
-
key={priority}
|
|
48
|
-
label={t(`main.tags.${priority.toLowerCase()}` as any)}
|
|
49
|
-
value={priority}
|
|
50
|
-
disableRipple
|
|
51
|
-
/>
|
|
52
|
-
)
|
|
53
|
-
})}
|
|
54
|
-
</CardTabs>
|
|
55
|
-
</SettingCardExpandable>
|
|
26
|
+
<BadgedValue badgeColor="info" showBadge={isRoutePriorityChanged}>
|
|
27
|
+
{routePriority === 'FASTEST'
|
|
28
|
+
? t('settings.routePriorityOptions.fastest.title')
|
|
29
|
+
: t('settings.routePriorityOptions.cheapest.title')}
|
|
30
|
+
</BadgedValue>
|
|
31
|
+
</CardButton>
|
|
56
32
|
)
|
|
57
33
|
}
|