@lifi/widget 3.0.1 → 3.1.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 (227) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/README.md +24 -5
  3. package/_esm/components/Card/CardIconButton.js +1 -0
  4. package/_esm/components/Card/CardIconButton.js.map +1 -1
  5. package/_esm/components/Card/CardLabel.d.ts +1 -1
  6. package/_esm/components/Card/CardLabel.js +8 -12
  7. package/_esm/components/Card/CardLabel.js.map +1 -1
  8. package/_esm/components/ChainSelect/ChainSelect.js +1 -1
  9. package/_esm/components/ChainSelect/ChainSelect.js.map +1 -1
  10. package/_esm/components/FeeBreakdownTooltip.d.ts +12 -0
  11. package/_esm/components/FeeBreakdownTooltip.js +13 -0
  12. package/_esm/components/FeeBreakdownTooltip.js.map +1 -0
  13. package/_esm/components/Header/CloseDrawerButton.js +1 -1
  14. package/_esm/components/Header/CloseDrawerButton.js.map +1 -1
  15. package/_esm/components/Header/SettingsButton.js +1 -1
  16. package/_esm/components/Header/SettingsButton.js.map +1 -1
  17. package/_esm/components/Header/TransactionHistoryButton.js +1 -1
  18. package/_esm/components/Header/TransactionHistoryButton.js.map +1 -1
  19. package/_esm/components/IconTypography.d.ts +3 -0
  20. package/_esm/components/IconTypography.js +8 -0
  21. package/_esm/components/IconTypography.js.map +1 -0
  22. package/_esm/components/PoweredBy/PoweredBy.js +1 -1
  23. package/_esm/components/PoweredBy/PoweredBy.js.map +1 -1
  24. package/_esm/components/ProgressToNextUpdate.js +1 -1
  25. package/_esm/components/ProgressToNextUpdate.js.map +1 -1
  26. package/_esm/components/RouteCard/RouteCard.js +7 -16
  27. package/_esm/components/RouteCard/RouteCard.js.map +1 -1
  28. package/_esm/components/RouteCard/RouteCard.style.d.ts +0 -3
  29. package/_esm/components/RouteCard/RouteCard.style.js +1 -7
  30. package/_esm/components/RouteCard/RouteCard.style.js.map +1 -1
  31. package/_esm/components/RouteCard/RouteCardEssentials.js +13 -14
  32. package/_esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  33. package/_esm/components/RouteCard/RouteCardEssentialsExpanded.js +4 -20
  34. package/_esm/components/RouteCard/RouteCardEssentialsExpanded.js.map +1 -1
  35. package/_esm/components/RouteCard/types.d.ts +1 -6
  36. package/_esm/components/Routes/RoutesExpanded.js +2 -4
  37. package/_esm/components/Routes/RoutesExpanded.js.map +1 -1
  38. package/_esm/components/SendToWallet/SendToWalletExpandButton.js +1 -1
  39. package/_esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  40. package/_esm/components/Step/Step.d.ts +1 -0
  41. package/_esm/components/Step/Step.js +2 -2
  42. package/_esm/components/Step/Step.js.map +1 -1
  43. package/_esm/components/Step/StepList.js +16 -7
  44. package/_esm/components/Step/StepList.js.map +1 -1
  45. package/_esm/components/Step/StepTimer.js +3 -3
  46. package/_esm/components/Step/StepTimer.js.map +1 -1
  47. package/_esm/components/StepActions/StepActions.js +5 -4
  48. package/_esm/components/StepActions/StepActions.js.map +1 -1
  49. package/_esm/components/Token/Token.d.ts +2 -0
  50. package/_esm/components/Token/Token.js +22 -8
  51. package/_esm/components/Token/Token.js.map +1 -1
  52. package/_esm/components/Token/Token.style.js +1 -0
  53. package/_esm/components/Token/Token.style.js.map +1 -1
  54. package/_esm/components/TokenRate.d.ts +7 -0
  55. package/_esm/components/TokenRate.js +41 -0
  56. package/_esm/components/TokenRate.js.map +1 -0
  57. package/_esm/components/TransactionDetails.d.ts +7 -0
  58. package/_esm/components/TransactionDetails.js +46 -0
  59. package/_esm/components/TransactionDetails.js.map +1 -0
  60. package/_esm/config/version.d.ts +1 -1
  61. package/_esm/config/version.js +1 -1
  62. package/_esm/hooks/timer/useInterval.d.ts +1 -0
  63. package/_esm/hooks/timer/useInterval.js +18 -0
  64. package/_esm/hooks/timer/useInterval.js.map +1 -0
  65. package/_esm/hooks/timer/useTimer.d.ts +18 -0
  66. package/_esm/hooks/timer/useTimer.js +61 -0
  67. package/_esm/hooks/timer/useTimer.js.map +1 -0
  68. package/_esm/hooks/timer/utils.d.ts +11 -0
  69. package/_esm/hooks/timer/utils.js +46 -0
  70. package/_esm/hooks/timer/utils.js.map +1 -0
  71. package/_esm/hooks/useAccount.js +4 -5
  72. package/_esm/hooks/useAccount.js.map +1 -1
  73. package/_esm/hooks/useAvailableChains.js +1 -0
  74. package/_esm/hooks/useAvailableChains.js.map +1 -1
  75. package/_esm/hooks/useGasRecommendation.js +1 -0
  76. package/_esm/hooks/useGasRecommendation.js.map +1 -1
  77. package/_esm/hooks/useRoutes.d.ts +4 -2
  78. package/_esm/hooks/useRoutes.js +17 -10
  79. package/_esm/hooks/useRoutes.js.map +1 -1
  80. package/_esm/hooks/useTokens.js +1 -0
  81. package/_esm/hooks/useTokens.js.map +1 -1
  82. package/_esm/hooks/useTools.js +1 -0
  83. package/_esm/hooks/useTools.js.map +1 -1
  84. package/_esm/hooks/useTransactionDetails.d.ts +1 -1
  85. package/_esm/hooks/useTransactionDetails.js +1 -1
  86. package/_esm/hooks/useTransactionDetails.js.map +1 -1
  87. package/_esm/hooks/useTransactionHistory.js.map +1 -1
  88. package/_esm/i18n/en.json +14 -20
  89. package/_esm/i18n/index.js +15 -15
  90. package/_esm/i18n/index.js.map +1 -1
  91. package/_esm/index.d.ts +2 -1
  92. package/_esm/index.js +1 -4
  93. package/_esm/index.js.map +1 -1
  94. package/_esm/pages/MainPage/ReviewButton.js +2 -4
  95. package/_esm/pages/MainPage/ReviewButton.js.map +1 -1
  96. package/_esm/pages/RoutesPage/RoutesPage.js +2 -4
  97. package/_esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  98. package/_esm/pages/SelectEnabledToolsPage.js +1 -1
  99. package/_esm/pages/SelectEnabledToolsPage.js.map +1 -1
  100. package/_esm/pages/SendToWallet/SendToWalletPage.js +1 -1
  101. package/_esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  102. package/_esm/pages/SettingsPage/ThemeSettings.js +1 -1
  103. package/_esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  104. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +5 -7
  105. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  106. package/_esm/pages/TransactionHistoryPage/TransactionHistoryItem.js +2 -2
  107. package/_esm/pages/TransactionHistoryPage/TransactionHistoryItem.js.map +1 -1
  108. package/_esm/pages/TransactionPage/ExchangeRateBottomSheet.js +2 -2
  109. package/_esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
  110. package/_esm/pages/TransactionPage/RouteTracker.d.ts +7 -0
  111. package/_esm/pages/TransactionPage/RouteTracker.js +39 -0
  112. package/_esm/pages/TransactionPage/RouteTracker.js.map +1 -0
  113. package/_esm/pages/TransactionPage/StartTransactionButton.d.ts +0 -1
  114. package/_esm/pages/TransactionPage/StartTransactionButton.js +0 -9
  115. package/_esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  116. package/_esm/pages/TransactionPage/TransactionPage.js +10 -21
  117. package/_esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  118. package/_esm/pages/TransactionPage/types.d.ts +0 -1
  119. package/_esm/providers/I18nProvider/I18nProvider.js +2 -0
  120. package/_esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  121. package/_esm/providers/I18nProvider/currencyExtendedFormatter.d.ts +1 -0
  122. package/_esm/providers/I18nProvider/currencyExtendedFormatter.js +13 -0
  123. package/_esm/providers/I18nProvider/currencyExtendedFormatter.js.map +1 -0
  124. package/_esm/providers/WalletProvider/EVMBaseProvider.js +18 -12
  125. package/_esm/providers/WalletProvider/EVMBaseProvider.js.map +1 -1
  126. package/_esm/stores/routes/createRouteExecutionStore.js +2 -2
  127. package/_esm/stores/routes/createRouteExecutionStore.js.map +1 -1
  128. package/_esm/stores/routes/types.d.ts +1 -1
  129. package/_esm/stores/routes/useSetExecutableRoute.d.ts +1 -1
  130. package/_esm/themes/createTheme.js +6 -0
  131. package/_esm/themes/createTheme.js.map +1 -1
  132. package/_esm/types/widget.d.ts +1 -2
  133. package/_esm/utils/converters.js +5 -13
  134. package/_esm/utils/converters.js.map +1 -1
  135. package/_esm/utils/fees.d.ts +3 -3
  136. package/_esm/utils/fees.js +18 -13
  137. package/_esm/utils/fees.js.map +1 -1
  138. package/_esm/utils/format.d.ts +13 -4
  139. package/_esm/utils/format.js +51 -13
  140. package/_esm/utils/format.js.map +1 -1
  141. package/components/Card/CardIconButton.tsx +1 -0
  142. package/components/Card/CardLabel.tsx +13 -29
  143. package/components/ChainSelect/ChainSelect.tsx +1 -9
  144. package/components/FeeBreakdownTooltip.tsx +66 -0
  145. package/components/Header/CloseDrawerButton.tsx +1 -1
  146. package/components/Header/SettingsButton.tsx +1 -1
  147. package/components/Header/TransactionHistoryButton.tsx +1 -1
  148. package/components/IconTypography.ts +9 -0
  149. package/components/PoweredBy/PoweredBy.tsx +1 -1
  150. package/components/ProgressToNextUpdate.tsx +0 -3
  151. package/components/RouteCard/RouteCard.style.ts +1 -9
  152. package/components/RouteCard/RouteCard.tsx +15 -71
  153. package/components/RouteCard/RouteCardEssentials.tsx +52 -81
  154. package/components/RouteCard/RouteCardEssentialsExpanded.tsx +17 -107
  155. package/components/RouteCard/types.ts +1 -7
  156. package/components/Routes/RoutesExpanded.tsx +3 -4
  157. package/components/SendToWallet/SendToWalletExpandButton.tsx +1 -6
  158. package/components/Step/Step.tsx +11 -2
  159. package/components/Step/StepList.tsx +19 -10
  160. package/components/Step/StepTimer.tsx +9 -6
  161. package/components/StepActions/StepActions.tsx +11 -14
  162. package/components/Token/Token.style.tsx +1 -0
  163. package/components/Token/Token.tsx +49 -9
  164. package/components/TokenRate.tsx +79 -0
  165. package/components/TransactionDetails.tsx +182 -0
  166. package/config/version.ts +1 -1
  167. package/hooks/timer/useInterval.ts +21 -0
  168. package/hooks/timer/useTimer.ts +91 -0
  169. package/hooks/timer/utils.ts +54 -0
  170. package/hooks/useAccount.ts +8 -5
  171. package/hooks/useAvailableChains.ts +2 -1
  172. package/hooks/useGasRecommendation.ts +1 -0
  173. package/hooks/useRoutes.ts +23 -13
  174. package/hooks/useTokens.ts +1 -0
  175. package/hooks/useTools.ts +2 -1
  176. package/hooks/useTransactionDetails.ts +3 -3
  177. package/hooks/useTransactionHistory.ts +1 -1
  178. package/i18n/en.json +14 -20
  179. package/i18n/index.ts +15 -15
  180. package/index.ts +2 -5
  181. package/package.json +15 -16
  182. package/pages/MainPage/ReviewButton.tsx +2 -4
  183. package/pages/RoutesPage/RoutesPage.tsx +3 -4
  184. package/pages/SelectEnabledToolsPage.tsx +1 -1
  185. package/pages/SendToWallet/SendToWalletPage.tsx +1 -1
  186. package/pages/SettingsPage/ThemeSettings.tsx +1 -1
  187. package/pages/TransactionDetailsPage/TransactionDetailsPage.tsx +9 -20
  188. package/pages/TransactionHistoryPage/TransactionHistoryItem.tsx +3 -5
  189. package/pages/TransactionPage/ExchangeRateBottomSheet.tsx +0 -2
  190. package/pages/TransactionPage/RouteTracker.tsx +68 -0
  191. package/pages/TransactionPage/StartTransactionButton.tsx +0 -24
  192. package/pages/TransactionPage/TransactionPage.tsx +21 -48
  193. package/pages/TransactionPage/types.ts +0 -1
  194. package/providers/I18nProvider/I18nProvider.tsx +6 -0
  195. package/providers/I18nProvider/currencyExtendedFormatter.ts +15 -0
  196. package/providers/WalletProvider/EVMBaseProvider.tsx +13 -7
  197. package/stores/routes/createRouteExecutionStore.ts +2 -2
  198. package/stores/routes/types.ts +1 -1
  199. package/themes/createTheme.ts +6 -0
  200. package/types/widget.ts +1 -2
  201. package/utils/converters.ts +5 -13
  202. package/utils/fees.ts +23 -24
  203. package/utils/format.ts +67 -20
  204. package/_esm/components/Insurance/Insurance.d.ts +0 -2
  205. package/_esm/components/Insurance/Insurance.js +0 -8
  206. package/_esm/components/Insurance/Insurance.js.map +0 -1
  207. package/_esm/components/Insurance/InsuranceCard.d.ts +0 -2
  208. package/_esm/components/Insurance/InsuranceCard.js +0 -36
  209. package/_esm/components/Insurance/InsuranceCard.js.map +0 -1
  210. package/_esm/components/Insurance/InsuranceCollapsed.d.ts +0 -2
  211. package/_esm/components/Insurance/InsuranceCollapsed.js +0 -29
  212. package/_esm/components/Insurance/InsuranceCollapsed.js.map +0 -1
  213. package/_esm/components/Insurance/types.d.ts +0 -19
  214. package/_esm/components/Insurance/types.js +0 -2
  215. package/_esm/components/Insurance/types.js.map +0 -1
  216. package/_esm/components/StepActions/StepFeeBreakdown.d.ts +0 -4
  217. package/_esm/components/StepActions/StepFeeBreakdown.js +0 -42
  218. package/_esm/components/StepActions/StepFeeBreakdown.js.map +0 -1
  219. package/_esm/icons/InsuraceLogo.d.ts +0 -2
  220. package/_esm/icons/InsuraceLogo.js +0 -8
  221. package/_esm/icons/InsuraceLogo.js.map +0 -1
  222. package/components/Insurance/Insurance.tsx +0 -22
  223. package/components/Insurance/InsuranceCard.tsx +0 -119
  224. package/components/Insurance/InsuranceCollapsed.tsx +0 -59
  225. package/components/Insurance/types.ts +0 -24
  226. package/components/StepActions/StepFeeBreakdown.tsx +0 -108
  227. package/icons/InsuraceLogo.tsx +0 -46
@@ -92,13 +92,16 @@ export const useAccount = (args?: UseAccountArgs): AccountResult => {
92
92
  const evm: Account = { ...account, chainType: ChainType.EVM };
93
93
  const accounts = [evm, svm];
94
94
  const connectedAccounts = [evm, svm].filter(
95
- (account) => account.isConnected,
95
+ (account) => account.isConnected && account.address,
96
96
  );
97
97
  return {
98
- account: hasChainTypeArgs
99
- ? accounts.find((account) => account.chainType === args?.chainType) ??
100
- defaultAccount
101
- : accounts.find((account) => account.isConnected) ?? defaultAccount,
98
+ account:
99
+ accounts.find(
100
+ (account) =>
101
+ (!hasChainTypeArgs || account.chainType === args?.chainType) &&
102
+ account.isConnected &&
103
+ account.address,
104
+ ) ?? defaultAccount,
102
105
  // We need to return only connected account list
103
106
  accounts: connectedAccounts,
104
107
  };
@@ -32,7 +32,8 @@ export const useAvailableChains = () => {
32
32
  config.setChains(availableChains);
33
33
  return availableChains;
34
34
  },
35
- refetchInterval: 300000,
35
+ refetchInterval: 300_000,
36
+ staleTime: 300_000,
36
37
  });
37
38
 
38
39
  const getChainById = useCallback(
@@ -41,5 +41,6 @@ export const useGasRecommendation = (
41
41
  },
42
42
  enabled: checkRecommendationLiFuel || checkRecommendationMaxButton,
43
43
  refetchInterval,
44
+ staleTime: refetchInterval,
44
45
  });
45
46
  };
@@ -5,6 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
5
5
  import { parseUnits } from 'viem';
6
6
  import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js';
7
7
  import { useFieldValues } from '../stores/form/useFieldValues.js';
8
+ import { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js';
8
9
  import { useSettings } from '../stores/settings/useSettings.js';
9
10
  import { defaultSlippage } from '../stores/settings/useSettingsStore.js';
10
11
  import { WidgetEvent } from '../types/events.js';
@@ -20,12 +21,13 @@ import { useWidgetEvents } from './useWidgetEvents.js';
20
21
  const refetchTime = 60_000;
21
22
 
22
23
  interface RoutesProps {
23
- insurableRoute?: Route;
24
+ observableRoute?: Route;
24
25
  }
25
26
 
26
- export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
27
- const { subvariant, sdkConfig, insurance, contractTool, bridges, exchanges } =
27
+ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
28
+ const { subvariant, sdkConfig, contractTool, bridges, exchanges } =
28
29
  useWidgetConfig();
30
+ const setExecutableRoute = useSetExecutableRoute();
29
31
  const queryClient = useQueryClient();
30
32
  const emitter = useWidgetEvents();
31
33
  const swapOnly = useSwapOnly();
@@ -135,8 +137,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
135
137
  sdkConfig?.routeOptions?.allowSwitchChain,
136
138
  enabledRefuel && enabledAutoRefuel,
137
139
  gasRecommendationFromAmount,
138
- insurance,
139
- insurableRoute?.id,
140
+ observableRoute?.id,
140
141
  ] as const;
141
142
 
142
143
  const { data, isLoading, isFetching, isFetched, dataUpdatedAt, refetch } =
@@ -165,8 +166,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
165
166
  allowSwitchChain,
166
167
  enabledRefuel,
167
168
  gasRecommendationFromAmount,
168
- insurance,
169
- insurableRouteId,
169
+ observableRouteId,
170
170
  ],
171
171
  signal,
172
172
  }) => {
@@ -178,8 +178,8 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
178
178
 
179
179
  const allowBridges = swapOnly
180
180
  ? []
181
- : insurableRoute
182
- ? insurableRoute.steps.flatMap((step) =>
181
+ : observableRoute
182
+ ? observableRoute.steps.flatMap((step) =>
183
183
  step.includedSteps.reduce((toolKeys, includedStep) => {
184
184
  if (includedStep.type === 'cross') {
185
185
  toolKeys.push(includedStep.toolDetails.key);
@@ -188,9 +188,8 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
188
188
  }, [] as string[]),
189
189
  )
190
190
  : allowedBridges;
191
-
192
- const allowExchanges = insurableRoute
193
- ? insurableRoute.steps.flatMap((step) =>
191
+ const allowExchanges = observableRoute
192
+ ? observableRoute.steps.flatMap((step) =>
194
193
  step.includedSteps.reduce((toolKeys, includedStep) => {
195
194
  if (includedStep.type === 'swap') {
196
195
  toolKeys.push(includedStep.toolDetails.key);
@@ -299,7 +298,6 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
299
298
  : undefined,
300
299
  }
301
300
  : undefined,
302
- insurance: insurance ? Boolean(insurableRoute) : undefined,
303
301
  order: routePriority,
304
302
  slippage: formattedSlippage,
305
303
  },
@@ -350,6 +348,16 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
350
348
  },
351
349
  });
352
350
 
351
+ const setReviewableRoute = (route: Route) => {
352
+ const queryDataKey = queryKey.toSpliced(queryKey.length - 1, 1, route.id);
353
+ queryClient.setQueryData(
354
+ queryDataKey,
355
+ { routes: [route] },
356
+ { updatedAt: dataUpdatedAt },
357
+ );
358
+ setExecutableRoute(route);
359
+ };
360
+
353
361
  return {
354
362
  routes: data?.routes,
355
363
  isLoading: isEnabled && isLoading,
@@ -360,5 +368,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
360
368
  refetch,
361
369
  fromChain,
362
370
  toChain,
371
+ queryKey,
372
+ setReviewableRoute,
363
373
  };
364
374
  };
@@ -11,6 +11,7 @@ export const useTokens = (selectedChainId?: number) => {
11
11
  queryKey: ['tokens'],
12
12
  queryFn: () => getTokens({ chainTypes: [ChainType.EVM, ChainType.SVM] }),
13
13
  refetchInterval: 3_600_000,
14
+ staleTime: 3_600_000,
14
15
  });
15
16
  const {
16
17
  chains,
package/hooks/useTools.ts CHANGED
@@ -35,7 +35,8 @@ export const useTools = () => {
35
35
  );
36
36
  return result;
37
37
  },
38
- refetchInterval: 180000,
38
+ refetchInterval: 180_000,
39
+ staleTime: 180_000,
39
40
  });
40
41
 
41
42
  return { tools: data };
@@ -7,7 +7,7 @@ import {
7
7
  } from '@tanstack/react-query';
8
8
  import { useAccount } from './useAccount.js';
9
9
 
10
- export const useTransactionDetails = (transactionHash: string) => {
10
+ export const useTransactionDetails = (transactionHash?: string) => {
11
11
  const { account, accounts } = useAccount();
12
12
  const queryClient = useQueryClient();
13
13
 
@@ -51,8 +51,8 @@ export const useTransactionDetails = (transactionHash: string) => {
51
51
  return transaction;
52
52
  }
53
53
  },
54
- refetchInterval: 300000,
55
- enabled: Boolean(account.isConnected),
54
+ refetchInterval: 300_000,
55
+ enabled: account.isConnected && Boolean(transactionHash),
56
56
  initialData: () => {
57
57
  for (const account of accounts) {
58
58
  const transaction = queryClient
@@ -28,7 +28,7 @@ export const useTransactionHistory = () => {
28
28
 
29
29
  return response.transfers;
30
30
  }) as QueryFunction<StatusResponse[], (string | undefined)[], never>,
31
- refetchInterval: 300000,
31
+ refetchInterval: 300_000,
32
32
  enabled: Boolean(account.address),
33
33
  })),
34
34
  combine: (results) => {
package/i18n/en.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "title": "Language"
5
5
  },
6
6
  "format": {
7
- "currency": "{{value, currency(currency: USD)}}",
7
+ "currency": "{{value, currencyExt(currency: USD)}}",
8
8
  "number": "{{value, number(maximumFractionDigits: 9)}}"
9
9
  },
10
10
  "button": {
@@ -90,7 +90,7 @@
90
90
  },
91
91
  "success": {
92
92
  "message": {
93
- "exchangePartiallySuccessful": "We've tried to complete the transaction, but {{tool}} ran out of liquidity for {{tokenSymbol}} token.",
93
+ "exchangePartiallySuccessful": "We've tried to complete the transaction, but {{tool}} couldn't proceed due to either slippage settings or lack of liquidity for the {{tokenSymbol}} token.",
94
94
  "exchangeSuccessful": "There are now {{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}} in {{walletAddress}} wallet on {{chainName}} chain.",
95
95
  "purchaseSuccessful": "You now own {{assetName}} in {{walletAddress}} wallet on {{chainName}} chain."
96
96
  },
@@ -162,14 +162,16 @@
162
162
  },
163
163
  "tooltip": {
164
164
  "estimatedTime": "Estimated execution time in minutes.",
165
+ "minReceived": "The estimated minimum amount may change until the swapping/bridging transaction is signed. For 2-step transfers, this applies until the second step transaction is signed.",
165
166
  "notFound": {
166
167
  "text": "We couldn't find this page.",
167
168
  "title": "404"
168
169
  },
169
- "numberOfSteps": "A number of exchange steps. Each step can contain 1-2 transactions that require a signature.",
170
+ "numberOfSteps": "Each exchange step can contain 1-2 transactions that require a signature.",
171
+ "priceImpact": "The estimated value difference between the source and destination tokens.",
170
172
  "progressToNextUpdate": "Quotes will update in {{value}} seconds. <0/> Click here to update now.",
171
- "settingsModified": "Settings (modified)",
172
173
  "selectAll": "Select all",
174
+ "settingsModified": "Settings (modified)",
173
175
  "deselectAll": "Deselect all"
174
176
  },
175
177
  "main": {
@@ -180,21 +182,22 @@
180
182
  "depositStepDetails": "Deposit via {{tool}}",
181
183
  "featuredTokens": "Featured tokens",
182
184
  "fees": {
183
- "estimated": "estimated fees",
184
- "networkEstimated": "Estimated network fees:",
185
- "networkPaid": "Paid network fees:",
186
- "paid": "paid fees",
187
- "providerEstimated": "Estimated provider fees:",
188
- "providerPaid": "Paid provider fees:"
185
+ "estimated": "estimated costs",
186
+ "network": "Network cost",
187
+ "paid": "paid costs",
188
+ "provider": "Provider fee"
189
189
  },
190
190
  "from": "From",
191
191
  "fromAmount": "You pay",
192
192
  "gasCost": "Gas cost",
193
193
  "inProgress": "in progress",
194
+ "maxSlippage": "Max. slippage",
195
+ "minReceived": "Min. received",
194
196
  "myTokens": "My tokens",
195
197
  "onChain": "on {{chainName}}",
196
198
  "ownedBy": "Owned by",
197
199
  "popularTokens": "Popular tokens",
200
+ "priceImpact": "Price impact",
198
201
  "process": {
199
202
  "bridge": {
200
203
  "actionRequired": "Please sign the transaction",
@@ -251,10 +254,7 @@
251
254
  "swapStepDetails": "Swap on {{chain}} via {{tool}}",
252
255
  "tags": {
253
256
  "cheapest": "Best Return",
254
- "fastest": "Fastest",
255
- "insurable": "Insurable",
256
- "insurance": "Insurance",
257
- "insured": "Insured"
257
+ "fastest": "Fastest"
258
258
  },
259
259
  "to": "To",
260
260
  "tokenOnChain": "{{tokenSymbol}} on {{chainName}}",
@@ -262,12 +262,6 @@
262
262
  "tokenSearch": "Search by token name or address",
263
263
  "valueLoss": "Value loss"
264
264
  },
265
- "insurance": {
266
- "bridgeExploits": "Bridge malfunctions, hacks or exploits",
267
- "insure": "Insure <0>{{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}}</0> in transit.",
268
- "insured": "You've insured <0>{{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}}</0> in transit:",
269
- "slippageError": "Error in slippage for tokens received"
270
- },
271
265
  "settings": {
272
266
  "theme": "Theme",
273
267
  "enabledBridges": "Bridges",
package/i18n/index.ts CHANGED
@@ -1,17 +1,17 @@
1
- import bn from './bn.json';
2
- import de from './de.json';
3
- import en from './en.json';
4
- import es from './es.json';
5
- import fr from './fr.json';
6
- import id from './id.json';
7
- import it from './it.json';
8
- import ja from './ja.json';
9
- import ko from './ko.json';
10
- import pt from './pt.json';
11
- import th from './th.json';
12
- import tr from './tr.json';
13
- import uk from './uk.json';
14
- import vi from './vi.json';
15
- import zh from './zh.json';
1
+ import bn from './bn.json' assert { type: 'json' };
2
+ import de from './de.json' assert { type: 'json' };
3
+ import en from './en.json' assert { type: 'json' };
4
+ import es from './es.json' assert { type: 'json' };
5
+ import fr from './fr.json' assert { type: 'json' };
6
+ import id from './id.json' assert { type: 'json' };
7
+ import it from './it.json' assert { type: 'json' };
8
+ import ja from './ja.json' assert { type: 'json' };
9
+ import ko from './ko.json' assert { type: 'json' };
10
+ import pt from './pt.json' assert { type: 'json' };
11
+ import th from './th.json' assert { type: 'json' };
12
+ import tr from './tr.json' assert { type: 'json' };
13
+ import uk from './uk.json' assert { type: 'json' };
14
+ import vi from './vi.json' assert { type: 'json' };
15
+ import zh from './zh.json' assert { type: 'json' };
16
16
 
17
17
  export { bn, de, en, es, fr, id, it, ja, ko, pt, th, tr, uk, vi, zh };
package/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from '@lifi/types';
1
2
  export { App as LiFiWidget } from './App.js';
2
3
  export type { WidgetDrawer } from './AppDrawer.js';
3
4
  export * from './components/ContractComponent/ItemPrice.js';
@@ -18,9 +19,5 @@ export * from './themes/palettes.js';
18
19
  export { watermelonLightTheme } from './themes/watermelonLight.js';
19
20
  export { windows95Theme } from './themes/windows95.js';
20
21
  export * from './types/events.js';
21
- export * from './types/token.js';
22
+ export type { TokenAmount } from './types/token.js';
22
23
  export * from './types/widget.js';
23
-
24
- // ClassNameGenerator.configure((componentName) =>
25
- // componentName.replace('Mui', 'LiFi'),
26
- // );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "type": "module",
6
6
  "main": "./_esm/index.js",
@@ -34,29 +34,28 @@
34
34
  "dependencies": {
35
35
  "@emotion/react": "^11.11.4",
36
36
  "@emotion/styled": "^11.11.5",
37
- "@lifi/sdk": "^3.0.0",
38
- "@lifi/wallet-management": "^3.0.0",
39
- "@mui/icons-material": "^5.15.20",
40
- "@mui/lab": "^5.0.0-alpha.170",
41
- "@mui/material": "^5.15.20",
37
+ "@lifi/sdk": "^3.0.1",
38
+ "@lifi/wallet-management": "^3.0.1",
39
+ "@mui/icons-material": "^5.16.1",
40
+ "@mui/lab": "^5.0.0-alpha.172",
41
+ "@mui/material": "^5.16.1",
42
42
  "@solana/wallet-adapter-base": "^0.9.23",
43
43
  "@solana/wallet-adapter-react": "^0.15.35",
44
- "@solana/web3.js": "^1.93.2",
45
- "@tanstack/react-query": "^5.48.0",
46
- "@tanstack/react-virtual": "^3.7.0",
47
- "i18next": "^23.11.5",
44
+ "@solana/web3.js": "^1.95.0",
45
+ "@tanstack/react-query": "^5.51.1",
46
+ "@tanstack/react-virtual": "^3.8.3",
47
+ "i18next": "^23.12.1",
48
48
  "microdiff": "^1.4.0",
49
49
  "mitt": "^3.0.1",
50
50
  "react": "^18.3.1",
51
51
  "react-dom": "^18.3.1",
52
52
  "react-i18next": "^14.1.2",
53
- "react-intersection-observer": "^9.10.3",
54
- "react-router-dom": "^6.24.0",
55
- "react-timer-hook": "^3.0.7",
53
+ "react-intersection-observer": "^9.13.0",
54
+ "react-router-dom": "^6.24.1",
56
55
  "uuid": "^10.0.0",
57
- "viem": "^2.16.2",
58
- "wagmi": "^2.10.7",
59
- "zustand": "^4.5.3"
56
+ "viem": "^2.17.4",
57
+ "wagmi": "^2.10.10",
58
+ "zustand": "^4.5.4"
60
59
  },
61
60
  "peerDependencies": {
62
61
  "@emotion/react": "^11.11.0",
@@ -5,25 +5,23 @@ import { useRoutes } from '../../hooks/useRoutes.js';
5
5
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
6
6
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
7
7
  import { useFieldValues } from '../../stores/form/useFieldValues.js';
8
- import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';
9
8
  import { useSplitSubvariantStore } from '../../stores/settings/useSplitSubvariantStore.js';
10
9
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
11
10
 
12
11
  export const ReviewButton: React.FC = () => {
13
12
  const { t } = useTranslation();
14
13
  const navigate = useNavigate();
15
- const setExecutableRoute = useSetExecutableRoute();
16
14
  const { subvariant } = useWidgetConfig();
17
15
  const splitState = useSplitSubvariantStore((state) => state.state);
18
16
  const [toAddress] = useFieldValues('toAddress');
19
17
  const { requiredToAddress } = useToAddressRequirements();
20
- const { routes } = useRoutes();
18
+ const { routes, setReviewableRoute } = useRoutes();
21
19
 
22
20
  const currentRoute = routes?.[0];
23
21
 
24
22
  const handleClick = async () => {
25
23
  if (currentRoute) {
26
- setExecutableRoute(currentRoute);
24
+ setReviewableRoute(currentRoute);
27
25
  navigate(navigationRoutes.transactionExecution, {
28
26
  state: { routeId: currentRoute.id },
29
27
  });
@@ -13,21 +13,20 @@ import { useNavigateBack } from '../../hooks/useNavigateBack.js';
13
13
  import { useRoutes } from '../../hooks/useRoutes.js';
14
14
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
15
15
  import { useFieldValues } from '../../stores/form/useFieldValues.js';
16
- import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';
17
16
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
18
17
  import { Stack } from './RoutesPage.style.js';
19
18
 
20
19
  export const RoutesPage: React.FC<BoxProps> = () => {
21
20
  const { navigate } = useNavigateBack();
22
- const setExecutableRoute = useSetExecutableRoute();
23
21
  const {
24
22
  routes,
25
23
  isLoading,
26
24
  isFetching,
27
25
  dataUpdatedAt,
28
26
  refetchTime,
29
- refetch,
30
27
  fromChain,
28
+ refetch,
29
+ setReviewableRoute,
31
30
  } = useRoutes();
32
31
  const { account } = useAccount({ chainType: fromChain?.chainType });
33
32
  const [toAddress] = useFieldValues('toAddress');
@@ -52,7 +51,7 @@ export const RoutesPage: React.FC<BoxProps> = () => {
52
51
  useHeader(t(`header.youGet`), headerAction);
53
52
 
54
53
  const handleRouteClick = (route: Route) => {
55
- setExecutableRoute(route);
54
+ setReviewableRoute(route);
56
55
  navigate(navigationRoutes.transactionExecution, {
57
56
  state: { routeId: route.id },
58
57
  });
@@ -41,7 +41,7 @@ const SelectAllCheckbox: React.FC<SelectAllCheckboxProps> = ({
41
41
  : t('tooltip.selectAll');
42
42
 
43
43
  return (
44
- <Tooltip title={tooltipTitle} arrow>
44
+ <Tooltip title={tooltipTitle}>
45
45
  <IconButton
46
46
  size="medium"
47
47
  edge={theme?.navigation?.edge ? 'end' : false}
@@ -217,7 +217,7 @@ export const SendToWalletPage = () => {
217
217
  >
218
218
  {t('button.done')}
219
219
  </ButtonTertiary>
220
- <Tooltip title={t('button.bookmark')} arrow>
220
+ <Tooltip title={t('button.bookmark')}>
221
221
  <SendToWalletIconButton
222
222
  onClick={handleBookmarkAddress}
223
223
  loading={isBookmarkButtonLoading}
@@ -29,7 +29,7 @@ const ThemeTab: React.FC<ThemeTabProps> = ({
29
29
  Icon,
30
30
  ...props
31
31
  }) => (
32
- <Tooltip title={title} arrow>
32
+ <Tooltip title={title}>
33
33
  <Tab icon={Icon} value={value} {...props} disableRipple />
34
34
  </Tooltip>
35
35
  );
@@ -7,9 +7,9 @@ import { useLocation } from 'react-router-dom';
7
7
  import { Card } from '../../components/Card/Card.js';
8
8
  import { CardTitle } from '../../components/Card/CardTitle.js';
9
9
  import { ContractComponent } from '../../components/ContractComponent/ContractComponent.js';
10
- import { Insurance } from '../../components/Insurance/Insurance.js';
11
10
  import { PageContainer } from '../../components/PageContainer.js';
12
11
  import { getStepList } from '../../components/Step/StepList.js';
12
+ import { TransactionDetails } from '../../components/TransactionDetails.js';
13
13
  import { useHeader } from '../../hooks/useHeader.js';
14
14
  import { useNavigateBack } from '../../hooks/useNavigateBack.js';
15
15
  import { useTools } from '../../hooks/useTools.js';
@@ -18,7 +18,6 @@ import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.j
18
18
  import { useRouteExecutionStore } from '../../stores/routes/RouteExecutionStore.js';
19
19
  import { getSourceTxHash } from '../../stores/routes/utils.js';
20
20
  import { buildRouteFromTxHistory } from '../../utils/converters.js';
21
- import { formatTokenAmount } from '../../utils/format.js';
22
21
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
23
22
  import { ContactSupportButton } from './ContactSupportButton.js';
24
23
  import { TransactionDetailsSkeleton } from './TransactionDetailsSkeleton.js';
@@ -34,7 +33,7 @@ export const TransactionDetailsPage: React.FC = () => {
34
33
  );
35
34
 
36
35
  const { transaction, isLoading } = useTransactionDetails(
37
- state?.transactionHash,
36
+ !storedRouteExecution && state?.transactionHash,
38
37
  );
39
38
 
40
39
  const title =
@@ -71,8 +70,6 @@ export const TransactionDetailsPage: React.FC = () => {
71
70
 
72
71
  const sourceTxHash = getSourceTxHash(routeExecution?.route);
73
72
 
74
- const insuranceCoverageId = sourceTxHash ?? routeExecution?.route.fromAddress;
75
-
76
73
  let supportId = sourceTxHash ?? routeExecution?.route.id ?? '';
77
74
 
78
75
  if (process.env.NODE_ENV === 'development') {
@@ -97,14 +94,14 @@ export const TransactionDetailsPage: React.FC = () => {
97
94
  pb={1}
98
95
  >
99
96
  <Typography fontSize={12}>
100
- {new Intl.DateTimeFormat(i18n.language, {
97
+ {startedAt.toLocaleString(i18n.language, {
101
98
  dateStyle: 'long',
102
- }).format(startedAt)}
99
+ })}
103
100
  </Typography>
104
101
  <Typography fontSize={12}>
105
- {new Intl.DateTimeFormat(i18n.language, {
102
+ {startedAt.toLocaleString(i18n.language, {
106
103
  timeStyle: 'short',
107
- }).format(startedAt)}
104
+ })}
108
105
  </Typography>
109
106
  </Box>
110
107
  {getStepList(routeExecution?.route, subvariant)}
@@ -113,17 +110,9 @@ export const TransactionDetailsPage: React.FC = () => {
113
110
  {contractSecondaryComponent}
114
111
  </ContractComponent>
115
112
  ) : null}
116
- {routeExecution?.route?.insurance?.state === 'INSURED' ? (
117
- <Insurance
118
- status={routeExecution.status}
119
- feeAmountUsd={routeExecution.route.insurance.feeAmountUsd}
120
- insuredAmount={formatTokenAmount(
121
- BigInt(routeExecution.route.toAmountMin),
122
- routeExecution.route.toToken.decimals,
123
- )}
124
- insuredTokenSymbol={routeExecution.route.toToken.symbol}
125
- insurableRouteId={routeExecution.route.id}
126
- insuranceCoverageId={insuranceCoverageId}
113
+ {routeExecution?.route ? (
114
+ <TransactionDetails
115
+ route={routeExecution?.route}
127
116
  sx={{ marginTop: 2 }}
128
117
  />
129
118
  ) : null}
@@ -80,14 +80,12 @@ export const TransactionHistoryItem: React.FC<{
80
80
  px={2}
81
81
  >
82
82
  <Typography fontSize={12}>
83
- {new Intl.DateTimeFormat(i18n.language, { dateStyle: 'long' }).format(
84
- startedAt,
85
- )}
83
+ {startedAt.toLocaleString(i18n.language, { dateStyle: 'long' })}
86
84
  </Typography>
87
85
  <Typography fontSize={12}>
88
- {new Intl.DateTimeFormat(i18n.language, {
86
+ {startedAt.toLocaleString(i18n.language, {
89
87
  timeStyle: 'short',
90
- }).format(startedAt)}
88
+ })}
91
89
  </Typography>
92
90
  </Box>
93
91
  <Box px={2} py={2}>
@@ -126,7 +126,6 @@ const ExchangeRateBottomSheetContent: React.FC<
126
126
  value: formatTokenAmount(
127
127
  BigInt(data.oldToAmount),
128
128
  data.toToken.decimals,
129
- 5,
130
129
  ),
131
130
  })}{' '}
132
131
  {data?.toToken.symbol}
@@ -139,7 +138,6 @@ const ExchangeRateBottomSheetContent: React.FC<
139
138
  value: formatTokenAmount(
140
139
  BigInt(data?.newToAmount),
141
140
  data?.toToken.decimals,
142
- 5,
143
141
  ),
144
142
  })}{' '}
145
143
  {data?.toToken.symbol}
@@ -0,0 +1,68 @@
1
+ import type { Dispatch, SetStateAction } from 'react';
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { ProgressToNextUpdate } from '../../components/ProgressToNextUpdate.js';
4
+ import { useRoutes } from '../../hooks/useRoutes.js';
5
+ import { useRouteExecutionStoreContext } from '../../stores/routes/RouteExecutionStore.js';
6
+ import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';
7
+
8
+ export interface RouteTrackerProps {
9
+ observableRouteId: string;
10
+ onChange: Dispatch<SetStateAction<string>>;
11
+ onFetching: Dispatch<SetStateAction<boolean>>;
12
+ }
13
+
14
+ export const RouteTracker = ({
15
+ observableRouteId,
16
+ onChange,
17
+ onFetching,
18
+ }: RouteTrackerProps) => {
19
+ const routeExecutionStore = useRouteExecutionStoreContext();
20
+ const setExecutableRoute = useSetExecutableRoute();
21
+ const [observableRoute] = useState(
22
+ () => routeExecutionStore.getState().routes[observableRouteId]?.route,
23
+ );
24
+ const observableRouteIdRef = useRef(observableRoute?.id);
25
+ const { routes, isFetching, dataUpdatedAt, refetchTime, refetch } = useRoutes(
26
+ { observableRoute },
27
+ );
28
+ const currentRoute = routes?.[0];
29
+
30
+ /**
31
+ * The reviewable route is the route that the user currently sees on the review page.
32
+ * The observable route is the route for which we track bridges and exchanges.
33
+ * This allows us to query the route using the same tool each time we refresh.
34
+ * The observable and reviewable routes can be the same when we first enter the review page.
35
+ */
36
+ useEffect(() => {
37
+ if (
38
+ observableRouteIdRef.current &&
39
+ currentRoute &&
40
+ observableRouteIdRef.current !== currentRoute.id
41
+ ) {
42
+ const reviewableRouteId = observableRouteIdRef.current;
43
+ observableRouteIdRef.current = currentRoute.id;
44
+ setExecutableRoute(currentRoute, [observableRouteId, reviewableRouteId]);
45
+ onChange(currentRoute.id);
46
+ }
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ }, [currentRoute?.id, observableRouteId]);
49
+
50
+ useEffect(() => {
51
+ onFetching(isFetching);
52
+ }, [isFetching, onFetching]);
53
+
54
+ const handleRefetch = () => {
55
+ refetch();
56
+ };
57
+
58
+ return (
59
+ <ProgressToNextUpdate
60
+ updatedAt={dataUpdatedAt || new Date().getTime()}
61
+ timeToUpdate={refetchTime}
62
+ isLoading={isFetching}
63
+ onClick={handleRefetch}
64
+ sx={{ marginRight: -1 }}
65
+ size="medium"
66
+ />
67
+ );
68
+ };