@lifi/widget 3.17.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/esm/components/Card/CardLabel.d.ts +1 -1
  3. package/dist/esm/components/Card/CardLabel.js +14 -3
  4. package/dist/esm/components/Card/CardLabel.js.map +1 -1
  5. package/dist/esm/components/FeeBreakdownTooltip.d.ts +1 -0
  6. package/dist/esm/components/FeeBreakdownTooltip.js +3 -3
  7. package/dist/esm/components/FeeBreakdownTooltip.js.map +1 -1
  8. package/dist/esm/components/Messages/WarningMessages.d.ts +1 -0
  9. package/dist/esm/components/Messages/WarningMessages.js +4 -4
  10. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  11. package/dist/esm/components/Messages/useMessageQueue.d.ts +2 -2
  12. package/dist/esm/components/Messages/useMessageQueue.js +5 -4
  13. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  14. package/dist/esm/components/RouteCard/RouteCard.js +11 -5
  15. package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
  16. package/dist/esm/components/RouteCard/RouteCardEssentials.js +9 -5
  17. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  18. package/dist/esm/components/Routes/RoutesExpanded.js +1 -4
  19. package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
  20. package/dist/esm/components/Step/StepProcess.js +2 -1
  21. package/dist/esm/components/Step/StepProcess.js.map +1 -1
  22. package/dist/esm/components/StepActions/StepActions.js +20 -15
  23. package/dist/esm/components/StepActions/StepActions.js.map +1 -1
  24. package/dist/esm/components/StepActions/types.d.ts +1 -0
  25. package/dist/esm/components/Timer/RouteTimer.js +11 -2
  26. package/dist/esm/components/Timer/RouteTimer.js.map +1 -1
  27. package/dist/esm/components/Timer/StepTimer.js +11 -2
  28. package/dist/esm/components/Timer/StepTimer.js.map +1 -1
  29. package/dist/esm/components/Token/Token.js +1 -1
  30. package/dist/esm/components/Token/Token.js.map +1 -1
  31. package/dist/esm/components/TransactionDetails.js +20 -14
  32. package/dist/esm/components/TransactionDetails.js.map +1 -1
  33. package/dist/esm/config/version.d.ts +1 -1
  34. package/dist/esm/config/version.js +1 -1
  35. package/dist/esm/hooks/useGasRefuel.js +2 -2
  36. package/dist/esm/hooks/useGasRefuel.js.map +1 -1
  37. package/dist/esm/hooks/useGasSufficiency.js +17 -3
  38. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  39. package/dist/esm/hooks/useIsBatchingSupported.d.ts +5 -0
  40. package/dist/esm/hooks/useIsBatchingSupported.js +19 -0
  41. package/dist/esm/hooks/useIsBatchingSupported.js.map +1 -0
  42. package/dist/esm/hooks/useProcessMessage.js +22 -6
  43. package/dist/esm/hooks/useProcessMessage.js.map +1 -1
  44. package/dist/esm/hooks/useRoutes.d.ts +3 -3
  45. package/dist/esm/hooks/useRoutes.js +119 -70
  46. package/dist/esm/hooks/useRoutes.js.map +1 -1
  47. package/dist/esm/i18n/en.json +29 -17
  48. package/dist/esm/pages/MainPage/ReviewButton.js +1 -4
  49. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  50. package/dist/esm/pages/RoutesPage/RoutesPage.js +1 -4
  51. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  52. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +1 -1
  53. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  54. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +6 -2
  55. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  56. package/dist/esm/pages/TransactionPage/TransactionPage.js +1 -1
  57. package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  58. package/dist/esm/providers/WalletProvider/SDKProviders.js +2 -15
  59. package/dist/esm/providers/WalletProvider/SDKProviders.js.map +1 -1
  60. package/dist/esm/types/widget.d.ts +3 -1
  61. package/dist/esm/types/widget.js +1 -0
  62. package/dist/esm/types/widget.js.map +1 -1
  63. package/dist/esm/utils/chainType.d.ts +1 -0
  64. package/dist/esm/utils/chainType.js +2 -0
  65. package/dist/esm/utils/chainType.js.map +1 -1
  66. package/dist/esm/utils/timer.d.ts +7 -0
  67. package/dist/esm/utils/timer.js +16 -0
  68. package/dist/esm/utils/timer.js.map +1 -0
  69. package/package.json +12 -12
  70. package/package.json.tmp +90 -0
  71. package/src/components/Card/CardLabel.tsx +29 -4
  72. package/src/components/FeeBreakdownTooltip.tsx +5 -2
  73. package/src/components/Messages/WarningMessages.tsx +5 -3
  74. package/src/components/Messages/useMessageQueue.ts +5 -4
  75. package/src/components/RouteCard/RouteCard.tsx +23 -8
  76. package/src/components/RouteCard/RouteCardEssentials.tsx +13 -5
  77. package/src/components/Routes/RoutesExpanded.tsx +1 -5
  78. package/src/components/Step/StepProcess.tsx +2 -1
  79. package/src/components/StepActions/StepActions.tsx +18 -6
  80. package/src/components/StepActions/types.ts +1 -0
  81. package/src/components/Timer/RouteTimer.tsx +13 -2
  82. package/src/components/Timer/StepTimer.tsx +15 -5
  83. package/src/components/Token/Token.tsx +1 -1
  84. package/src/components/TransactionDetails.tsx +51 -23
  85. package/src/config/version.ts +1 -1
  86. package/src/hooks/useGasRefuel.ts +2 -2
  87. package/src/hooks/useGasSufficiency.ts +23 -7
  88. package/src/hooks/useIsBatchingSupported.ts +24 -0
  89. package/src/hooks/useProcessMessage.ts +26 -5
  90. package/src/hooks/useRoutes.ts +148 -78
  91. package/src/i18n/en.json +29 -17
  92. package/src/pages/MainPage/ReviewButton.tsx +1 -6
  93. package/src/pages/RoutesPage/RoutesPage.tsx +2 -5
  94. package/src/pages/TransactionPage/StartTransactionButton.tsx +1 -1
  95. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +9 -2
  96. package/src/pages/TransactionPage/TransactionPage.tsx +1 -1
  97. package/src/providers/WalletProvider/SDKProviders.tsx +2 -16
  98. package/src/types/widget.ts +2 -0
  99. package/src/utils/chainType.ts +2 -0
  100. package/src/utils/timer.ts +28 -0
  101. package/dist/esm/components/Messages/GasMessage.d.ts +0 -7
  102. package/dist/esm/components/Messages/GasMessage.js +0 -13
  103. package/dist/esm/components/Messages/GasMessage.js.map +0 -1
  104. package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.d.ts +0 -8
  105. package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.js +0 -95
  106. package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.js.map +0 -1
  107. package/src/components/Messages/GasMessage.tsx +0 -35
  108. package/src/providers/WalletProvider/getSafeMultisigConfig.ts +0 -144
@@ -29,7 +29,8 @@ export const StepProcess: React.FC<{
29
29
  <CircularProgress process={process} />
30
30
  <Typography
31
31
  sx={{
32
- mx: 2,
32
+ marginLeft: 2,
33
+ marginRight: 0.5,
33
34
  flex: 1,
34
35
  fontSize: 14,
35
36
  fontWeight: process.error ? 600 : 400,
@@ -1,4 +1,5 @@
1
1
  import type { LiFiStep, StepExtended } from '@lifi/sdk'
2
+ import { isRelayerStep } from '@lifi/sdk'
2
3
  import { ArrowForward, ExpandLess, ExpandMore } from '@mui/icons-material'
3
4
  import type { StepIconProps } from '@mui/material'
4
5
  import {
@@ -26,7 +27,6 @@ import {
26
27
  StepLabel,
27
28
  StepLabelTypography,
28
29
  } from './StepActions.style.js'
29
- import { StepFees } from './StepFees.js'
30
30
  import type {
31
31
  IncludedStepsProps,
32
32
  StepActionsProps,
@@ -95,7 +95,7 @@ export const StepActions: React.FC<StepActionsProps> = ({
95
95
  tool: toolDetails.name,
96
96
  })}
97
97
  </Typography>
98
- <StepFees ml={2} step={step} />
98
+ {/* <StepFees ml={2} step={step} /> */}
99
99
  </Box>
100
100
  {dense ? (
101
101
  <CardIconButton onClick={handleExpand} size="small">
@@ -160,6 +160,8 @@ export const IncludedSteps: React.FC<IncludedStepsProps> = ({ step }) => {
160
160
  ) : null
161
161
  }
162
162
 
163
+ const hasRelayerSupport = isRelayerStep(step)
164
+
163
165
  return (
164
166
  <Box
165
167
  sx={{
@@ -173,7 +175,11 @@ export const IncludedSteps: React.FC<IncludedStepsProps> = ({ step }) => {
173
175
  >
174
176
  {includedSteps.map((step, i, includedSteps) => (
175
177
  <MuiStep key={step.id} expanded>
176
- <StepLabel StepIconComponent={StepIconComponent}>
178
+ <StepLabel
179
+ slots={{
180
+ stepIcon: StepIconComponent,
181
+ }}
182
+ >
177
183
  {step.type === 'custom' && subvariant === 'custom' ? (
178
184
  <CustomStepDetailsLabel
179
185
  step={step}
@@ -183,7 +189,11 @@ export const IncludedSteps: React.FC<IncludedStepsProps> = ({ step }) => {
183
189
  ) : step.type === 'cross' ? (
184
190
  <BridgeStepDetailsLabel step={step} />
185
191
  ) : step.type === 'protocol' ? (
186
- <ProtocolStepDetailsLabel step={step} feeConfig={feeConfig} />
192
+ <ProtocolStepDetailsLabel
193
+ step={step}
194
+ feeConfig={feeConfig}
195
+ relayerSupport={hasRelayerSupport}
196
+ />
187
197
  ) : (
188
198
  <SwapStepDetailsLabel step={step} />
189
199
  )}
@@ -345,14 +355,16 @@ export const SwapStepDetailsLabel: React.FC<
345
355
 
346
356
  export const ProtocolStepDetailsLabel: React.FC<
347
357
  Omit<StepDetailsLabelProps, 'variant'>
348
- > = ({ step, feeConfig }) => {
358
+ > = ({ step, feeConfig, relayerSupport }) => {
349
359
  const { t } = useTranslation()
350
360
  return (
351
361
  <StepLabelTypography>
352
362
  {step.toolDetails.key === 'feeCollection'
353
363
  ? feeConfig?.name
354
364
  ? t('main.fees.integrator', { tool: feeConfig.name })
355
- : t('main.fees.defaultIntegrator')
365
+ : relayerSupport
366
+ ? t('main.fees.relayerService')
367
+ : t('main.fees.defaultIntegrator')
356
368
  : step.toolDetails.key === 'gasZip'
357
369
  ? t('main.refuelStepDetails', {
358
370
  tool: step.toolDetails.name,
@@ -16,6 +16,7 @@ export interface StepDetailsLabelProps {
16
16
  subvariant?: Extract<WidgetSubvariant, 'custom'>
17
17
  subvariantOptions?: SubvariantOptions
18
18
  feeConfig?: WidgetFeeConfig
19
+ relayerSupport?: boolean
19
20
  }
20
21
 
21
22
  export interface IncludedStepsProps {
@@ -1,5 +1,8 @@
1
1
  import type { RouteExtended } from '@lifi/sdk'
2
+
2
3
  import { useStopwatch } from '../../hooks/timer/useStopwatch.js'
4
+ import { useSettings } from '../../stores/settings/useSettings.js'
5
+ import { formatTimer } from '../../utils/timer.js'
3
6
  import { TimerContent } from './TimerContent.js'
4
7
 
5
8
  export const RouteTimer: React.FC<{
@@ -9,14 +12,22 @@ export const RouteTimer: React.FC<{
9
12
  const firstActiveProcess = firstActiveStep?.execution?.process.at(0)
10
13
 
11
14
  const startTime = new Date(firstActiveProcess?.startedAt ?? Date.now())
12
- const { seconds, minutes } = useStopwatch({
15
+ const { seconds, minutes, days, hours } = useStopwatch({
13
16
  autoStart: true,
14
17
  offsetTimestamp: startTime,
15
18
  })
16
19
 
20
+ const { language } = useSettings(['language'])
21
+
17
22
  return (
18
23
  <TimerContent>
19
- {`${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`}
24
+ {formatTimer({
25
+ days,
26
+ hours,
27
+ seconds,
28
+ minutes,
29
+ locale: language,
30
+ })}
20
31
  </TimerContent>
21
32
  )
22
33
  }
@@ -2,6 +2,8 @@ import type { LiFiStepExtended } from '@lifi/sdk'
2
2
  import { useEffect, useState } from 'react'
3
3
  import { useTranslation } from 'react-i18next'
4
4
  import { useStopwatch } from '../../hooks/timer/useStopwatch.js'
5
+ import { useSettings } from '../../stores/settings/useSettings.js'
6
+ import { formatTimer } from '../../utils/timer.js'
5
7
  import { TimerContent } from './TimerContent.js'
6
8
 
7
9
  const getFirstExecutionProcess = (step: LiFiStepExtended) =>
@@ -18,15 +20,17 @@ export const StepTimer: React.FC<{
18
20
  hideInProgress?: boolean
19
21
  }> = ({ step }) => {
20
22
  const { i18n } = useTranslation()
23
+ const { language } = useSettings(['language'])
21
24
 
22
25
  const [isExecutionStarted, setExecutionStarted] = useState(
23
26
  () => !!getExecutionProcess(step)
24
27
  )
25
28
 
26
- const { seconds, minutes, isRunning, pause, reset, start } = useStopwatch({
27
- autoStart: true,
28
- offsetTimestamp: getStartTimestamp(step),
29
- })
29
+ const { seconds, minutes, days, hours, isRunning, pause, reset, start } =
30
+ useStopwatch({
31
+ autoStart: true,
32
+ offsetTimestamp: getStartTimestamp(step),
33
+ })
30
34
 
31
35
  useEffect(() => {
32
36
  const executionProcess = getExecutionProcess(step)
@@ -78,7 +82,13 @@ export const StepTimer: React.FC<{
78
82
 
79
83
  return (
80
84
  <TimerContent>
81
- {`${minutes}:${seconds < 10 ? `0${seconds}` : seconds}`}
85
+ {formatTimer({
86
+ locale: language,
87
+ days,
88
+ hours,
89
+ minutes,
90
+ seconds,
91
+ })}
82
92
  </TimerContent>
83
93
  )
84
94
  }
@@ -177,7 +177,7 @@ export const TokenBase: FC<TokenProps & BoxProps> = ({
177
177
  &#x2022;
178
178
  </TextSecondary>
179
179
  ) : null}
180
- {step ? (
180
+ {!disableDescription && step ? (
181
181
  <TokenStep
182
182
  step={step}
183
183
  stepVisible={stepVisible}
@@ -1,4 +1,5 @@
1
1
  import type { RouteExtended } from '@lifi/sdk'
2
+ import { isRelayerStep } from '@lifi/sdk'
2
3
  import {
3
4
  ExpandLess,
4
5
  ExpandMore,
@@ -62,8 +63,10 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
62
63
  )
63
64
  }
64
65
 
66
+ const hasRelayerSupport = route.steps.some(isRelayerStep)
67
+
65
68
  const showIntegratorFeeCollectionDetails =
66
- feeAmountUSD || Number.isFinite(feeConfig?.fee)
69
+ (feeAmountUSD || Number.isFinite(feeConfig?.fee)) && !hasRelayerSupport
67
70
 
68
71
  return (
69
72
  <Card selectionColor="secondary" {...props}>
@@ -86,7 +89,11 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
86
89
  <TokenRate route={route} />
87
90
  </Box>
88
91
  <Collapse timeout={100} in={!cardExpanded} mountOnEnter>
89
- <FeeBreakdownTooltip gasCosts={gasCosts} feeCosts={feeCosts}>
92
+ <FeeBreakdownTooltip
93
+ gasCosts={gasCosts}
94
+ feeCosts={feeCosts}
95
+ relayerSupport={hasRelayerSupport}
96
+ >
90
97
  <Box
91
98
  onClick={toggleCard}
92
99
  // biome-ignore lint/a11y/useSemanticElements:
@@ -102,15 +109,17 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
102
109
  <LocalGasStationRounded fontSize="inherit" />
103
110
  </IconTypography>
104
111
  <Typography
105
- data-value={combinedFeesUSD}
112
+ data-value={hasRelayerSupport ? 0 : combinedFeesUSD}
106
113
  sx={{
107
114
  fontSize: 14,
108
115
  color: 'text.primary',
109
- fontWeight: '600',
116
+ fontWeight: 600,
110
117
  lineHeight: 1.429,
111
118
  }}
112
119
  >
113
- {t('format.currency', { value: combinedFeesUSD })}
120
+ {hasRelayerSupport
121
+ ? t('main.fees.free')
122
+ : t('format.currency', { value: combinedFeesUSD })}
114
123
  </Typography>
115
124
  </Box>
116
125
  </FeeBreakdownTooltip>
@@ -138,11 +147,19 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
138
147
  }}
139
148
  >
140
149
  <Typography variant="body2">{t('main.fees.network')}</Typography>
141
- <FeeBreakdownTooltip gasCosts={gasCosts}>
142
- <Typography variant="body2">
143
- {t('format.currency', {
144
- value: gasCostUSD,
145
- })}
150
+ <FeeBreakdownTooltip
151
+ gasCosts={gasCosts}
152
+ relayerSupport={hasRelayerSupport}
153
+ >
154
+ <Typography
155
+ variant="body2"
156
+ sx={{ fontWeight: 600, cursor: 'help' }}
157
+ >
158
+ {hasRelayerSupport
159
+ ? t('main.fees.free')
160
+ : t('format.currency', {
161
+ value: gasCostUSD,
162
+ })}
146
163
  </Typography>
147
164
  </FeeBreakdownTooltip>
148
165
  </Box>
@@ -156,7 +173,10 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
156
173
  >
157
174
  <Typography variant="body2">{t('main.fees.provider')}</Typography>
158
175
  <FeeBreakdownTooltip feeCosts={feeCosts}>
159
- <Typography variant="body2">
176
+ <Typography
177
+ variant="body2"
178
+ sx={{ fontWeight: 600, cursor: 'help' }}
179
+ >
160
180
  {t('format.currency', {
161
181
  value: feeCostUSD,
162
182
  })}
@@ -180,16 +200,18 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
180
200
  {feeConfig?.name ? (
181
201
  <Tooltip
182
202
  title={t('tooltip.feeCollection', { tool: feeConfig.name })}
183
- sx={{ cursor: 'help' }}
184
203
  >
185
- <Typography variant="body2">
204
+ <Typography
205
+ variant="body2"
206
+ sx={{ fontWeight: 600, cursor: 'help' }}
207
+ >
186
208
  {t('format.currency', {
187
209
  value: feeAmountUSD,
188
210
  })}
189
211
  </Typography>
190
212
  </Tooltip>
191
213
  ) : (
192
- <Typography variant="body2">
214
+ <Typography variant="body2" sx={{ fontWeight: 600 }}>
193
215
  {t('format.currency', {
194
216
  value: feeAmountUSD,
195
217
  })}
@@ -205,8 +227,11 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
205
227
  }}
206
228
  >
207
229
  <Typography variant="body2">{t('main.priceImpact')}</Typography>
208
- <Tooltip title={t('tooltip.priceImpact')} sx={{ cursor: 'help' }}>
209
- <Typography variant="body2">
230
+ <Tooltip title={t('tooltip.priceImpact')}>
231
+ <Typography
232
+ variant="body2"
233
+ sx={{ fontWeight: 600, cursor: 'help' }}
234
+ >
210
235
  {t('format.percent', { value: priceImpact })}
211
236
  </Typography>
212
237
  </Tooltip>
@@ -221,8 +246,11 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
221
246
  }}
222
247
  >
223
248
  <Typography variant="body2">{t('main.maxSlippage')}</Typography>
224
- <Tooltip title={t('tooltip.slippage')} sx={{ cursor: 'help' }}>
225
- <Typography variant="body2">
249
+ <Tooltip title={t('tooltip.slippage')}>
250
+ <Typography
251
+ variant="body2"
252
+ sx={{ fontWeight: 600, cursor: 'help' }}
253
+ >
226
254
  {t('format.percent', {
227
255
  value: route.steps[0].action.slippage,
228
256
  })}
@@ -236,11 +264,11 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
236
264
  }}
237
265
  >
238
266
  <Typography variant="body2">{t('main.minReceived')}</Typography>
239
- <Tooltip
240
- title={t('tooltip.minReceived')}
241
- sx={{ cursor: 'help' }}
242
- >
243
- <Typography variant="body2">
267
+ <Tooltip title={t('tooltip.minReceived')}>
268
+ <Typography
269
+ variant="body2"
270
+ sx={{ fontWeight: 600, cursor: 'help' }}
271
+ >
244
272
  {t('format.tokenAmount', {
245
273
  value: formatTokenAmount(
246
274
  BigInt(route.toAmountMin),
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget'
2
- export const version = '3.17.0'
2
+ export const version = '3.18.0'
@@ -49,8 +49,8 @@ export const useGasRefuel = () => {
49
49
 
50
50
  const enabled = useMemo(() => {
51
51
  if (
52
- // We don't allow same chain refuel.
53
- // If a user runs out of gas, he can't send a source chain transaction.
52
+ // Same chain refuel is not allowed since users need gas on source chain to initiate transaction
53
+ // We allow refuel when bridging to native token since bridging routes may require gas for destination swaps
54
54
  fromChainId === toChainId ||
55
55
  !gasRecommendation?.available ||
56
56
  !gasRecommendation?.recommended ||
@@ -1,4 +1,5 @@
1
1
  import type { EVMChain, RouteExtended, Token } from '@lifi/sdk'
2
+ import { isRelayerStep } from '@lifi/sdk'
2
3
  import { useAccount } from '@lifi/wallet-management'
3
4
  import { useQuery } from '@tanstack/react-query'
4
5
  import { useAvailableChains } from './useAvailableChains.js'
@@ -22,19 +23,29 @@ export const useGasSufficiency = (route?: RouteExtended) => {
22
23
  chainType: getChainById(route?.fromChainId)?.chainType,
23
24
  })
24
25
 
25
- const { isContractAddress } = useIsContractAddress(
26
- account.address,
27
- route?.fromChainId,
28
- account.chainType
29
- )
26
+ const { isContractAddress, isLoading: isContractAddressLoading } =
27
+ useIsContractAddress(account.address, route?.fromChainId, account.chainType)
30
28
 
31
29
  const { data: insufficientGas, isLoading } = useQuery({
32
- queryKey: ['gas-sufficiency-check', account.address, route?.id],
30
+ queryKey: [
31
+ 'gas-sufficiency-check',
32
+ account.address,
33
+ route?.id,
34
+ isContractAddress,
35
+ ] as const,
33
36
  queryFn: async ({ queryKey: [, accountAddress] }) => {
34
37
  if (!route) {
35
38
  return
36
39
  }
37
40
 
41
+ // If we have a relayer step with a permit (EIP-2612) for the from token, we don't need to check for gas sufficiency
42
+ if (
43
+ isRelayerStep(route.steps[0]) &&
44
+ route.steps[0].permits.some((permit) => permit.permitType === 'Permit')
45
+ ) {
46
+ return
47
+ }
48
+
38
49
  // We assume that LI.Fuel protocol always refuels the destination chain
39
50
  const hasRefuelStep = route.steps
40
51
  .flatMap((step) => step.includedSteps)
@@ -136,7 +147,12 @@ export const useGasSufficiency = (route?: RouteExtended) => {
136
147
  return gasCostResult
137
148
  },
138
149
 
139
- enabled: Boolean(!isContractAddress && account.address && route),
150
+ enabled: Boolean(
151
+ !isContractAddress &&
152
+ !isContractAddressLoading &&
153
+ account.address &&
154
+ route
155
+ ),
140
156
  refetchInterval,
141
157
  staleTime: refetchInterval,
142
158
  })
@@ -0,0 +1,24 @@
1
+ import { ChainType, isBatchingSupported } from '@lifi/sdk'
2
+ import type { ExtendedChain } from '@lifi/sdk'
3
+ import { useQuery } from '@tanstack/react-query'
4
+
5
+ export function useIsBatchingSupported(
6
+ chain?: ExtendedChain,
7
+ address?: string
8
+ ) {
9
+ const enabled = chain && chain.chainType === ChainType.EVM && !!address
10
+ const { data, isLoading } = useQuery({
11
+ queryKey: ['isBatchingSupported', chain?.id, address],
12
+ queryFn: () => {
13
+ return isBatchingSupported({ chainId: chain!.id })
14
+ },
15
+ enabled,
16
+ staleTime: 3_600_000,
17
+ retry: false,
18
+ })
19
+
20
+ return {
21
+ isBatchingSupported: data,
22
+ isBatchingSupportedLoading: enabled && isLoading,
23
+ }
24
+ }
@@ -39,6 +39,7 @@ const processStatusMessages: Record<
39
39
  ProcessStatus,
40
40
  (
41
41
  t: TFunction,
42
+ step: LiFiStep,
42
43
  subvariant?: WidgetSubvariant,
43
44
  subvariantOptions?: SubvariantOptions
44
45
  ) => string
@@ -47,19 +48,34 @@ const processStatusMessages: Record<
47
48
  > = {
48
49
  TOKEN_ALLOWANCE: {
49
50
  STARTED: (t) => t('main.process.tokenAllowance.started'),
50
- ACTION_REQUIRED: (t) => t('main.process.tokenAllowance.pending'),
51
- PENDING: (t) => t('main.process.tokenAllowance.pending'),
52
- DONE: (t) => t('main.process.tokenAllowance.done'),
51
+ ACTION_REQUIRED: (t, step) =>
52
+ t('main.process.tokenAllowance.actionRequired', {
53
+ tokenSymbol: step.action.fromToken.symbol,
54
+ }),
55
+ PENDING: (t, step) =>
56
+ t('main.process.tokenAllowance.pending', {
57
+ tokenSymbol: step.action.fromToken.symbol,
58
+ }),
59
+ DONE: (t, step) =>
60
+ t('main.process.tokenAllowance.done', {
61
+ tokenSymbol: step.action.fromToken.symbol,
62
+ }),
53
63
  },
54
64
  SWITCH_CHAIN: {
55
65
  ACTION_REQUIRED: (t) => t('main.process.switchChain.actionRequired'),
56
66
  DONE: (t) => t('main.process.switchChain.done'),
57
67
  },
68
+ PERMIT: {
69
+ STARTED: (t) => t('main.process.permit.started'),
70
+ ACTION_REQUIRED: (t) => t('main.process.permit.actionRequired'),
71
+ PENDING: (t) => t('main.process.permit.pending'),
72
+ DONE: (t) => t('main.process.permit.done'),
73
+ },
58
74
  SWAP: {
59
75
  STARTED: (t) => t('main.process.swap.started'),
60
76
  ACTION_REQUIRED: (t) => t('main.process.swap.actionRequired'),
61
77
  PENDING: (t) => t('main.process.swap.pending'),
62
- DONE: (t, subvariant, subvariantOptions) =>
78
+ DONE: (t, _, subvariant, subvariantOptions) =>
63
79
  subvariant === 'custom'
64
80
  ? t(`main.process.${subvariantOptions?.custom ?? 'checkout'}.done`)
65
81
  : t('main.process.swap.done'),
@@ -72,7 +88,7 @@ const processStatusMessages: Record<
72
88
  },
73
89
  RECEIVING_CHAIN: {
74
90
  PENDING: (t) => t('main.process.receivingChain.pending'),
75
- DONE: (t, subvariant, subvariantOptions) =>
91
+ DONE: (t, _, subvariant, subvariantOptions) =>
76
92
  subvariant === 'custom'
77
93
  ? t(`main.process.${subvariantOptions?.custom ?? 'checkout'}.done`)
78
94
  : t('main.process.receivingChain.done'),
@@ -193,6 +209,10 @@ export function getProcessMessage(
193
209
  title = t('error.title.transactionCanceled')
194
210
  message = getDefaultErrorMessage('error.message.transactionCanceled')
195
211
  break
212
+ case LiFiErrorCode.TransactionRejected:
213
+ title = t('error.title.transactionRejected')
214
+ message = getDefaultErrorMessage('error.message.transactionRejected')
215
+ break
196
216
  case LiFiErrorCode.TransactionConflict:
197
217
  title = t('error.title.transactionConflict')
198
218
  message = getDefaultErrorMessage('error.message.transactionConflict')
@@ -229,6 +249,7 @@ export function getProcessMessage(
229
249
  ]?.(t) ??
230
250
  processStatusMessages[process.type]?.[process.status]?.(
231
251
  t,
252
+ step,
232
253
  subvariant,
233
254
  subvariantOptions
234
255
  )