@lifi/widget 3.0.0-alpha.37 → 3.0.0-alpha.39

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 (146) hide show
  1. package/_esm/components/AppContainer.d.ts +5 -0
  2. package/_esm/components/AppContainer.js +1 -1
  3. package/_esm/components/AppContainer.js.map +1 -1
  4. package/_esm/components/Card/InputCard.js +1 -1
  5. package/_esm/components/Card/InputCard.js.map +1 -1
  6. package/_esm/components/ChainSelect/ChainSelect.js +8 -9
  7. package/_esm/components/ChainSelect/ChainSelect.js.map +1 -1
  8. package/_esm/components/Header/Header.style.d.ts +0 -3
  9. package/_esm/components/Header/Header.style.js +1 -7
  10. package/_esm/components/Header/Header.style.js.map +1 -1
  11. package/_esm/components/Header/NavigationHeader.js +1 -66
  12. package/_esm/components/Header/NavigationHeader.js.map +1 -1
  13. package/_esm/components/Header/NavigationTabs.js +3 -3
  14. package/_esm/components/Header/NavigationTabs.js.map +1 -1
  15. package/_esm/components/Skeleton/WidgetSkeleton.d.ts +2 -0
  16. package/_esm/components/Skeleton/WidgetSkeleton.js +29 -0
  17. package/_esm/components/Skeleton/WidgetSkeleton.js.map +1 -0
  18. package/_esm/components/Skeleton/WidgetSkeleton.style.d.ts +31 -0
  19. package/_esm/components/Skeleton/WidgetSkeleton.style.js +55 -0
  20. package/_esm/components/Skeleton/WidgetSkeleton.style.js.map +1 -0
  21. package/_esm/components/Tabs/Tabs.style.d.ts +3 -0
  22. package/_esm/components/Tabs/Tabs.style.js +17 -9
  23. package/_esm/components/Tabs/Tabs.style.js.map +1 -1
  24. package/_esm/config/version.d.ts +1 -1
  25. package/_esm/config/version.js +1 -1
  26. package/_esm/hooks/useAddressValidation.d.ts +1 -1
  27. package/_esm/hooks/useAddressValidation.js.map +1 -1
  28. package/_esm/hooks/useHeader.d.ts +2 -0
  29. package/_esm/hooks/useHeader.js +16 -0
  30. package/_esm/hooks/useHeader.js.map +1 -0
  31. package/_esm/hooks/useProcessMessage.js +4 -0
  32. package/_esm/hooks/useProcessMessage.js.map +1 -1
  33. package/_esm/hooks/useToken.js +1 -1
  34. package/_esm/hooks/useToken.js.map +1 -1
  35. package/_esm/i18n/en.json +4 -2
  36. package/_esm/index.d.ts +1 -0
  37. package/_esm/index.js +1 -0
  38. package/_esm/index.js.map +1 -1
  39. package/_esm/pages/ActiveTransactionsPage/ActiveTransactionsPage.js +4 -10
  40. package/_esm/pages/ActiveTransactionsPage/ActiveTransactionsPage.js.map +1 -1
  41. package/_esm/pages/LanguagesPage.js +3 -1
  42. package/_esm/pages/LanguagesPage.js.map +1 -1
  43. package/_esm/pages/MainPage/MainPage.js +9 -0
  44. package/_esm/pages/MainPage/MainPage.js.map +1 -1
  45. package/_esm/pages/RoutesPage/RoutesPage.js +6 -8
  46. package/_esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  47. package/_esm/pages/SelectChainPage/SelectChainPage.js +4 -0
  48. package/_esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  49. package/_esm/pages/SelectEnabledToolsPage.js +5 -8
  50. package/_esm/pages/SelectEnabledToolsPage.js.map +1 -1
  51. package/_esm/pages/SelectTokenPage/SelectTokenPage.js +11 -0
  52. package/_esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  53. package/_esm/pages/SelectWalletPage/SelectWalletPage.js +2 -0
  54. package/_esm/pages/SelectWalletPage/SelectWalletPage.js.map +1 -1
  55. package/_esm/pages/SendToWallet/BookmarksPage.js +2 -0
  56. package/_esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  57. package/_esm/pages/SendToWallet/ConnectedWalletsPage.js +2 -0
  58. package/_esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  59. package/_esm/pages/SendToWallet/RecentWalletsPage.js +2 -0
  60. package/_esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  61. package/_esm/pages/SendToWallet/SendToConfiguredWalletPage.js +2 -0
  62. package/_esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  63. package/_esm/pages/SendToWallet/SendToWalletPage.js +2 -0
  64. package/_esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  65. package/_esm/pages/SettingsPage/GasPriceSettings.js +2 -2
  66. package/_esm/pages/SettingsPage/GasPriceSettings.js.map +1 -1
  67. package/_esm/pages/SettingsPage/RoutePrioritySettings.js +2 -2
  68. package/_esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
  69. package/_esm/pages/SettingsPage/SettingsPage.js +4 -0
  70. package/_esm/pages/SettingsPage/SettingsPage.js.map +1 -1
  71. package/_esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js +8 -5
  72. package/_esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
  73. package/_esm/pages/SettingsPage/ThemeSettings.js +2 -2
  74. package/_esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  75. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +5 -0
  76. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  77. package/_esm/pages/TransactionHistoryPage/TransactionHistoryPage.js +4 -0
  78. package/_esm/pages/TransactionHistoryPage/TransactionHistoryPage.js.map +1 -1
  79. package/_esm/pages/TransactionPage/StatusBottomSheet.js +4 -3
  80. package/_esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
  81. package/_esm/pages/TransactionPage/StatusBottomSheet.style.d.ts +3 -0
  82. package/_esm/pages/TransactionPage/StatusBottomSheet.style.js +7 -0
  83. package/_esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
  84. package/_esm/pages/TransactionPage/TransactionPage.js +16 -11
  85. package/_esm/pages/TransactionPage/TransactionPage.js.map +1 -1
  86. package/_esm/stores/chains/createChainOrderStore.d.ts +2 -1
  87. package/_esm/stores/chains/createChainOrderStore.js +6 -5
  88. package/_esm/stores/chains/createChainOrderStore.js.map +1 -1
  89. package/_esm/stores/header/useHeaderStore.js.map +1 -1
  90. package/_esm/themes/azureLight.js +12 -0
  91. package/_esm/themes/azureLight.js.map +1 -1
  92. package/_esm/themes/createTheme.js +28 -2
  93. package/_esm/themes/createTheme.js.map +1 -1
  94. package/_esm/themes/watermelonLight.js.map +1 -1
  95. package/_esm/types/widget.d.ts +1 -1
  96. package/_esm/types/widget.js.map +1 -1
  97. package/_esm/utils/colors.d.ts +0 -1
  98. package/_esm/utils/colors.js +0 -3
  99. package/_esm/utils/colors.js.map +1 -1
  100. package/components/AppContainer.tsx +1 -1
  101. package/components/Card/InputCard.tsx +1 -1
  102. package/components/ChainSelect/ChainSelect.tsx +35 -32
  103. package/components/Header/Header.style.ts +0 -9
  104. package/components/Header/NavigationHeader.tsx +1 -67
  105. package/components/Header/NavigationTabs.tsx +4 -4
  106. package/components/Skeleton/WidgetSkeleton.style.tsx +63 -0
  107. package/components/Skeleton/WidgetSkeleton.tsx +136 -0
  108. package/components/Tabs/Tabs.style.tsx +20 -9
  109. package/config/version.ts +1 -1
  110. package/hooks/useAddressValidation.ts +2 -1
  111. package/hooks/useHeader.ts +18 -0
  112. package/hooks/useProcessMessage.ts +4 -0
  113. package/hooks/useToken.ts +1 -1
  114. package/i18n/en.json +4 -2
  115. package/index.ts +1 -0
  116. package/package.json +30 -18
  117. package/pages/ActiveTransactionsPage/ActiveTransactionsPage.tsx +11 -10
  118. package/pages/LanguagesPage.tsx +3 -1
  119. package/pages/MainPage/MainPage.tsx +11 -0
  120. package/pages/RoutesPage/RoutesPage.tsx +21 -18
  121. package/pages/SelectChainPage/SelectChainPage.tsx +5 -0
  122. package/pages/SelectEnabledToolsPage.tsx +17 -15
  123. package/pages/SelectTokenPage/SelectTokenPage.tsx +14 -0
  124. package/pages/SelectWalletPage/SelectWalletPage.tsx +3 -0
  125. package/pages/SendToWallet/BookmarksPage.tsx +3 -0
  126. package/pages/SendToWallet/ConnectedWalletsPage.tsx +2 -0
  127. package/pages/SendToWallet/RecentWalletsPage.tsx +3 -0
  128. package/pages/SendToWallet/SendToConfiguredWalletPage.tsx +3 -0
  129. package/pages/SendToWallet/SendToWalletPage.tsx +3 -0
  130. package/pages/SettingsPage/GasPriceSettings.tsx +3 -3
  131. package/pages/SettingsPage/RoutePrioritySettings.tsx +3 -3
  132. package/pages/SettingsPage/SettingsPage.tsx +5 -0
  133. package/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +10 -8
  134. package/pages/SettingsPage/ThemeSettings.tsx +3 -3
  135. package/pages/TransactionDetailsPage/TransactionDetailsPage.tsx +7 -0
  136. package/pages/TransactionHistoryPage/TransactionHistoryPage.tsx +5 -0
  137. package/pages/TransactionPage/StatusBottomSheet.style.tsx +8 -0
  138. package/pages/TransactionPage/StatusBottomSheet.tsx +18 -3
  139. package/pages/TransactionPage/TransactionPage.tsx +20 -14
  140. package/stores/chains/createChainOrderStore.ts +6 -5
  141. package/stores/header/useHeaderStore.tsx +0 -1
  142. package/themes/azureLight.ts +12 -0
  143. package/themes/createTheme.ts +36 -1
  144. package/themes/watermelonLight.ts +0 -2
  145. package/types/widget.ts +1 -0
  146. package/utils/colors.ts +0 -5
@@ -0,0 +1,136 @@
1
+ import { Skeleton, ThemeProvider, useMediaQuery } from '@mui/material';
2
+ import { useMemo } from 'react';
3
+ import { createTheme } from '../../themes/createTheme.js';
4
+ import type { WidgetConfigPartialProps } from '../../types/widget.js';
5
+ import {
6
+ AppExpandedContainer,
7
+ FlexContainer,
8
+ RelativeContainer,
9
+ } from '../AppContainer.js';
10
+ import { Container as HeaderContainer } from '../Header/Header.style.js';
11
+ import {
12
+ SkeletonAmountContainer,
13
+ SkeletonCard,
14
+ SkeletonCardRow,
15
+ SkeletonHeaderAppBar,
16
+ SkeletonInputCard,
17
+ SkeletonPoweredByContainer,
18
+ SkeletonReviewButton,
19
+ SkeletonReviewButtonContainer,
20
+ SkeletonSendToWalletButton,
21
+ SkeletonWalletMenuButtonContainer,
22
+ } from './WidgetSkeleton.style.js';
23
+
24
+ const SkeletonIcon = () => (
25
+ <Skeleton width={24} height={24} variant="rounded" />
26
+ );
27
+ const SkeletonWalletMenuButton = () => (
28
+ <SkeletonWalletMenuButtonContainer>
29
+ <Skeleton width={98} height={19} variant="text" />
30
+ <SkeletonIcon />
31
+ </SkeletonWalletMenuButtonContainer>
32
+ );
33
+
34
+ interface SkeletonSelectCardProps {
35
+ titleWidth?: number;
36
+ placeholderWidth?: number;
37
+ }
38
+ const SkeletonSelectCard = ({
39
+ titleWidth = 36,
40
+ placeholderWidth = 195,
41
+ }: SkeletonSelectCardProps) => (
42
+ <SkeletonCard elevation={0}>
43
+ <Skeleton width={titleWidth} height={22} variant="text" />
44
+ <SkeletonCardRow>
45
+ <Skeleton width={40} height={40} variant="circular" />
46
+ <Skeleton width={placeholderWidth} height={27} variant="text" />
47
+ </SkeletonCardRow>
48
+ </SkeletonCard>
49
+ );
50
+
51
+ const SkeletonYouPayCard = () => (
52
+ <SkeletonInputCard elevation={0}>
53
+ <Skeleton width={55} height={22} variant="text" />
54
+ <SkeletonCardRow>
55
+ <Skeleton width={40} height={40} variant="circular" />
56
+ <SkeletonAmountContainer>
57
+ <Skeleton
58
+ width={48}
59
+ height={37}
60
+ variant="text"
61
+ sx={{ marginTop: -0.75 }}
62
+ />
63
+ <Skeleton width={48} height={12} variant="text" />
64
+ </SkeletonAmountContainer>
65
+ </SkeletonCardRow>
66
+ </SkeletonInputCard>
67
+ );
68
+
69
+ export const WidgetSkeleton = ({ config }: WidgetConfigPartialProps) => {
70
+ const appearance = config?.appearance;
71
+ const hiddenUI = config?.hiddenUI || [];
72
+ const requiredUI = config?.requiredUI || [];
73
+ const configTheme = config?.theme;
74
+ const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
75
+ const appearanceMode =
76
+ !appearance || appearance === 'auto'
77
+ ? prefersDarkMode
78
+ ? 'dark'
79
+ : 'light'
80
+ : appearance;
81
+
82
+ const theme = useMemo(
83
+ () => createTheme(appearanceMode, configTheme),
84
+ [appearanceMode, configTheme],
85
+ );
86
+
87
+ return (
88
+ <ThemeProvider theme={theme}>
89
+ <AppExpandedContainer>
90
+ <RelativeContainer>
91
+ <HeaderContainer>
92
+ {!hiddenUI.includes('walletMenu') ? (
93
+ <SkeletonHeaderAppBar>
94
+ <SkeletonWalletMenuButton />
95
+ </SkeletonHeaderAppBar>
96
+ ) : null}
97
+ <SkeletonHeaderAppBar
98
+ sx={{ justifyContent: 'space-between', height: 40 }}
99
+ >
100
+ <Skeleton width={126} height={34} variant="text" />
101
+ <SkeletonIcon />
102
+ </SkeletonHeaderAppBar>
103
+ </HeaderContainer>
104
+ <FlexContainer
105
+ sx={{
106
+ gap: 2,
107
+ paddingBottom: hiddenUI.includes('poweredBy') ? 3 : 2,
108
+ }}
109
+ >
110
+ <SkeletonSelectCard />
111
+ <SkeletonSelectCard />
112
+ <SkeletonYouPayCard />
113
+ {requiredUI.includes('toAddress') ? (
114
+ <SkeletonSelectCard titleWidth={104} placeholderWidth={175} />
115
+ ) : null}
116
+ <SkeletonReviewButtonContainer>
117
+ <SkeletonReviewButton variant="contained" fullWidth>
118
+ &nbsp;
119
+ </SkeletonReviewButton>
120
+ {!requiredUI.includes('toAddress') ? (
121
+ <SkeletonSendToWalletButton variant="text" fullWidth>
122
+ &nbsp;
123
+ </SkeletonSendToWalletButton>
124
+ ) : null}
125
+ </SkeletonReviewButtonContainer>
126
+ {!hiddenUI.includes('poweredBy') ? (
127
+ <SkeletonPoweredByContainer>
128
+ <Skeleton width={96} height={18} variant="text" />
129
+ </SkeletonPoweredByContainer>
130
+ ) : null}
131
+ </FlexContainer>
132
+ </RelativeContainer>
133
+ </AppExpandedContainer>
134
+ </ThemeProvider>
135
+ );
136
+ };
@@ -7,19 +7,30 @@ import {
7
7
  tabClasses,
8
8
  tabsClasses,
9
9
  } from '@mui/material';
10
- import { getCardFieldsetBackgroundColor } from '../../utils/colors.js';
11
10
 
12
11
  export const Tabs = styled(MuiTabs)(({ theme }) => ({
13
- backgroundColor: getCardFieldsetBackgroundColor(theme),
14
- borderRadius: theme.shape.borderRadius,
15
- padding: theme.spacing(0.5),
16
12
  flex: 1,
17
13
  [`.${tabsClasses.indicator}`]: {
18
- height: '100%',
19
- width: '100%',
20
- backgroundColor: theme.palette.background.paper,
21
- borderRadius: theme.shape.borderRadius - 4,
22
- boxShadow: `0px 2px 4px ${alpha(theme.palette.common.black, 0.04)}`,
14
+ top: theme.spacing(0.5),
15
+ left: theme.spacing(0.5),
16
+ height: `calc(100% - ${theme.spacing(1)})`,
17
+ width: `calc(100% - ${theme.spacing(1)})`,
18
+ },
19
+ [`.${tabsClasses.fixed}`]: {
20
+ padding: theme.spacing(0.5),
21
+ },
22
+ }));
23
+
24
+ export const CardTabs = styled(Tabs)(({ theme }) => ({
25
+ backgroundColor:
26
+ theme.palette.mode === 'light'
27
+ ? alpha(theme.palette.common.black, 0.04)
28
+ : alpha(theme.palette.common.white, 0.08),
29
+ [`.${tabsClasses.indicator}`]: {
30
+ backgroundColor:
31
+ theme.palette.mode === 'light'
32
+ ? theme.palette.background.paper
33
+ : alpha(theme.palette.common.black, 0.56),
23
34
  },
24
35
  }));
25
36
 
package/config/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget';
2
- export const version = '3.0.0-alpha.37';
2
+ export const version = '3.0.0-alpha.39';
@@ -1,4 +1,5 @@
1
- import { Chain, getNameServiceAddress, type ChainType } from '@lifi/sdk';
1
+ import type { Chain, ChainType } from '@lifi/sdk';
2
+ import { getNameServiceAddress } from '@lifi/sdk';
2
3
  import { useMutation } from '@tanstack/react-query';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import { getChainTypeFromAddress } from '../utils/chainType.js';
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ import { useEffect } from 'react';
3
+ import { useHeaderStore } from '../stores/header/useHeaderStore.js';
4
+
5
+ export function useHeader(title: string, action?: ReactNode) {
6
+ const { setTitle, setAction } = useHeaderStore((state) => state);
7
+
8
+ useEffect(() => {
9
+ const removeTitle = setTitle(title);
10
+ const removeAction = action ? setAction(action) : undefined;
11
+ return () => {
12
+ removeTitle();
13
+ if (removeAction) {
14
+ removeAction();
15
+ }
16
+ };
17
+ }, [setTitle, setAction, action, title]);
18
+ }
@@ -173,6 +173,10 @@ export function getProcessMessage(
173
173
  title = t(`error.title.transactionFailed`);
174
174
  message = t(`error.message.transactionFailed`);
175
175
  break;
176
+ case LiFiErrorCode.WalletChangedDuringExecution:
177
+ title = t(`error.title.walletMismatch`);
178
+ message = t(`error.message.walletChangedDuringExecution`);
179
+ break;
176
180
  case LiFiErrorCode.TransactionUnderpriced:
177
181
  title = t(`error.title.transactionUnderpriced`);
178
182
  message = getDefaultErrorMessage();
package/hooks/useToken.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- import { useTokens } from './useTokens.js';
3
2
  import { useTokenSearch } from './useTokenSearch.js';
3
+ import { useTokens } from './useTokens.js';
4
4
 
5
5
  export const useToken = (chainId?: number, tokenAddress?: string) => {
6
6
  const { tokens, isLoading } = useTokens(chainId);
package/i18n/en.json CHANGED
@@ -134,7 +134,8 @@
134
134
  "transactionCanceled": "Transaction was canceled.",
135
135
  "transactionFailed": "Please check the block explorer for more information.",
136
136
  "transactionNotSent": "Transaction was not sent.",
137
- "unknown": "Please try again or contact support."
137
+ "unknown": "Please try again or contact support.",
138
+ "walletChangedDuringExecution": "The wallet address that requested the quote does not match the wallet address attempting to sign the transaction. Please ensure the same wallet address is used throughout the entire transaction execution."
138
139
  },
139
140
  "title": {
140
141
  "allowanceRequired": "Insufficient allowance",
@@ -155,7 +156,8 @@
155
156
  "walletAddressInvalid": "Wallet address or domain name is invalid",
156
157
  "walletAddressInvalid_chain": "Wallet address or domain name is invalid for selected destination chain {{chainName}}",
157
158
  "walletAddressRequired": "Wallet address is required.",
158
- "walletChainTypeInvalid": "Wallet address doesn't match the selected destination chain {{chainName}}"
159
+ "walletChainTypeInvalid": "Wallet address doesn't match the selected destination chain {{chainName}}",
160
+ "walletMismatch": "Wallet address mismatch"
159
161
  }
160
162
  },
161
163
  "tooltip": {
package/index.ts CHANGED
@@ -4,6 +4,7 @@ export * from './components/ContractComponent/ItemPrice.js';
4
4
  export * from './components/ContractComponent/NFT/NFT.js';
5
5
  export * from './components/ContractComponent/NFT/NFTBase.js';
6
6
  export * from './components/ContractComponent/NFT/types.js';
7
+ export * from './components/Skeleton/WidgetSkeleton.js';
7
8
  export * from './config/version.js';
8
9
  export { useAccount } from './hooks/useAccount.js';
9
10
  export { useAvailableChains } from './hooks/useAvailableChains.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "3.0.0-alpha.37",
3
+ "version": "3.0.0-alpha.39",
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,37 +34,49 @@
34
34
  "dependencies": {
35
35
  "@emotion/react": "^11.11.4",
36
36
  "@emotion/styled": "^11.11.5",
37
- "@lifi/sdk": "^3.0.0-alpha.58",
38
- "@lifi/wallet-management": "^3.0.0-alpha.24",
39
- "@mui/icons-material": "^5.15.15",
37
+ "@lifi/sdk": "^3.0.0-alpha.61",
38
+ "@lifi/wallet-management": "^3.0.0-alpha.26",
39
+ "@mui/icons-material": "^5.15.17",
40
40
  "@mui/lab": "^5.0.0-alpha.170",
41
- "@mui/material": "^5.15.15",
41
+ "@mui/material": "^5.15.17",
42
42
  "@solana/wallet-adapter-base": "^0.9.23",
43
43
  "@solana/wallet-adapter-react": "^0.15.35",
44
- "@solana/wallet-adapter-wallets": "^0.19.32",
45
- "@solana/web3.js": "^1.91.4",
46
- "@tanstack/react-query": "^5.29.0",
47
- "@tanstack/react-virtual": "^3.2.0",
48
- "i18next": "^23.10.1",
44
+ "@solana/web3.js": "^1.91.8",
45
+ "@tanstack/react-query": "^5.35.5",
46
+ "@tanstack/react-virtual": "^3.5.0",
47
+ "i18next": "^23.11.4",
49
48
  "microdiff": "^1.4.0",
50
49
  "mitt": "^3.0.1",
51
- "react": "^18.2.0",
52
- "react-dom": "^18.2.0",
53
- "react-i18next": "^14.1.0",
54
- "react-intersection-observer": "^9.8.1",
55
- "react-router-dom": "^6.22.3",
50
+ "react": "^18.3.1",
51
+ "react-dom": "^18.3.1",
52
+ "react-i18next": "^14.1.1",
53
+ "react-intersection-observer": "^9.10.2",
54
+ "react-router-dom": "^6.23.0",
56
55
  "react-timer-hook": "^3.0.7",
57
56
  "uuid": "^9.0.1",
58
- "viem": "^2.9.13",
59
- "wagmi": "^2.5.19",
57
+ "viem": "^2.10.3",
58
+ "wagmi": "^2.8.5",
60
59
  "zustand": "^4.5.2"
61
60
  },
62
61
  "peerDependencies": {
62
+ "@emotion/react": "^11.11.0",
63
+ "@emotion/styled": "^11.11.0",
64
+ "@lifi/sdk": "^3.0.0-alpha.0",
65
+ "@lifi/wallet-management": "^3.0.0-alpha.0",
66
+ "@mui/icons-material": "^5.15.0",
67
+ "@mui/material": "^5.15.0",
68
+ "@solana/wallet-adapter-base": "^0.9.0",
69
+ "@solana/wallet-adapter-react": "^0.15.0",
70
+ "@solana/web3.js": "^1.91.0",
63
71
  "@tanstack/react-query": "^5.17.0",
64
72
  "@types/react": "^18.2.0",
73
+ "i18next": "^23.11.0",
65
74
  "react": "^18.2.0",
66
75
  "react-dom": "^18.2.0",
67
- "wagmi": "^2.2.0"
76
+ "react-i18next": "^14.1.0",
77
+ "react-router-dom": "^6.22.0",
78
+ "wagmi": "^2.2.0",
79
+ "zustand": "^4.5.0"
68
80
  },
69
81
  "peerDependenciesMeta": {
70
82
  "@types/react": {
@@ -10,12 +10,12 @@ import {
10
10
  List,
11
11
  useTheme,
12
12
  } from '@mui/material';
13
- import { useCallback, useEffect, useState } from 'react';
13
+ import { useCallback, useMemo, useState } from 'react';
14
14
  import { useTranslation } from 'react-i18next';
15
15
  import { ActiveTransactionItem } from '../../components/ActiveTransactions/ActiveTransactionItem.js';
16
16
  import { Dialog } from '../../components/Dialog.js';
17
17
  import { PageContainer } from '../../components/PageContainer.js';
18
- import { useHeaderStoreContext } from '../../stores/header/useHeaderStore.js';
18
+ import { useHeader } from '../../hooks/useHeader.js';
19
19
  import { useRouteExecutionStore } from '../../stores/routes/RouteExecutionStore.js';
20
20
  import { useExecutingRoutesIds } from '../../stores/routes/useExecutingRoutesIds.js';
21
21
  import { ActiveTransactionsEmpty } from './ActiveTransactionsEmpty.js';
@@ -38,20 +38,21 @@ export const ActiveTransactionsPage = () => {
38
38
  const { t } = useTranslation();
39
39
  const executingRoutes = useExecutingRoutesIds();
40
40
  const deleteRoutes = useRouteExecutionStore((store) => store.deleteRoutes);
41
- const headerStoreContext = useHeaderStoreContext();
42
41
  const [open, setOpen] = useState(false);
43
42
 
44
43
  const toggleDialog = useCallback(() => {
45
44
  setOpen((open) => !open);
46
45
  }, []);
47
46
 
48
- useEffect(() => {
49
- if (executingRoutes.length) {
50
- return headerStoreContext
51
- .getState()
52
- .setAction(<DeleteIconButton onClick={toggleDialog} />);
53
- }
54
- }, [executingRoutes.length, headerStoreContext, toggleDialog]);
47
+ const headerAction = useMemo(
48
+ () =>
49
+ executingRoutes.length ? (
50
+ <DeleteIconButton onClick={toggleDialog} />
51
+ ) : undefined,
52
+ [executingRoutes.length, toggleDialog],
53
+ );
54
+
55
+ useHeader(t(`header.activeTransactions`), headerAction);
55
56
 
56
57
  if (!executingRoutes.length) {
57
58
  return <ActiveTransactionsEmpty />;
@@ -4,13 +4,15 @@ import { useTranslation } from 'react-i18next';
4
4
  import { ListItemText } from '../components/ListItemText.js';
5
5
  import { PageContainer } from '../components/PageContainer.js';
6
6
  import { SettingsListItemButton } from '../components/SettingsListItemButton.js';
7
+ import { useHeader } from '../hooks/useHeader.js';
7
8
  import { useLanguages } from '../hooks/useLanguages.js';
8
9
 
9
10
  export const LanguagesPage: React.FC = () => {
11
+ const { t } = useTranslation();
10
12
  const { selectedLanguageCode, availableLanguages, setLanguageWithCode } =
11
13
  useLanguages();
12
14
 
13
- const { t } = useTranslation();
15
+ useHeader(t(`language.title`));
14
16
 
15
17
  if (availableLanguages.length < 1) {
16
18
  return null;
@@ -1,4 +1,5 @@
1
1
  import { Box } from '@mui/material';
2
+ import { useTranslation } from 'react-i18next';
2
3
  import { ActiveTransactions } from '../../components/ActiveTransactions/ActiveTransactions.js';
3
4
  import { AmountInput } from '../../components/AmountInput/AmountInput.js';
4
5
  import { ContractComponent } from '../../components/ContractComponent/ContractComponent.js';
@@ -9,6 +10,7 @@ import { Routes } from '../../components/Routes/Routes.js';
9
10
  import { SelectChainAndToken } from '../../components/SelectChainAndToken.js';
10
11
  import { SendToWalletButton } from '../../components/SendToWallet/SendToWalletButton.js';
11
12
  import { SendToWalletExpandButton } from '../../components/SendToWallet/SendToWalletExpandButton.js';
13
+ import { useHeader } from '../../hooks/useHeader.js';
12
14
  import { useWideVariant } from '../../hooks/useWideVariant.js';
13
15
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
14
16
  import { HiddenUI } from '../../types/widget.js';
@@ -16,11 +18,20 @@ import { MainMessages } from './MainMessages.js';
16
18
  import { ReviewButton } from './ReviewButton.js';
17
19
 
18
20
  export const MainPage: React.FC = () => {
21
+ const { t } = useTranslation();
19
22
  const wideVariant = useWideVariant();
20
23
  const { subvariant, contractComponent, hiddenUI } = useWidgetConfig();
21
24
  const custom = subvariant === 'custom';
22
25
  const showPoweredBy = !hiddenUI?.includes(HiddenUI.PoweredBy);
23
26
 
27
+ const title =
28
+ subvariant === 'custom'
29
+ ? t(`header.checkout`)
30
+ : subvariant === 'refuel'
31
+ ? t(`header.gas`)
32
+ : t(`header.exchange`);
33
+ useHeader(title);
34
+
24
35
  return (
25
36
  <PageContainer>
26
37
  <ActiveTransactions sx={{ marginBottom: 2 }} />
@@ -1,17 +1,18 @@
1
1
  /* eslint-disable react/no-array-index-key */
2
2
  import type { Route } from '@lifi/sdk';
3
3
  import type { BoxProps } from '@mui/material';
4
- import { useEffect } from 'react';
4
+ import { useMemo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
5
6
  import { ProgressToNextUpdate } from '../../components/ProgressToNextUpdate.js';
6
7
  import { RouteCard } from '../../components/RouteCard/RouteCard.js';
7
8
  import { RouteCardSkeleton } from '../../components/RouteCard/RouteCardSkeleton.js';
8
9
  import { RouteNotFoundCard } from '../../components/RouteCard/RouteNotFoundCard.js';
9
10
  import { useAccount } from '../../hooks/useAccount.js';
11
+ import { useHeader } from '../../hooks/useHeader.js';
10
12
  import { useNavigateBack } from '../../hooks/useNavigateBack.js';
11
13
  import { useRoutes } from '../../hooks/useRoutes.js';
12
14
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
13
15
  import { useFieldValues } from '../../stores/form/useFieldValues.js';
14
- import { useHeaderStoreContext } from '../../stores/header/useHeaderStore.js';
15
16
  import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';
16
17
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
17
18
  import { Stack } from './RoutesPage.style.js';
@@ -19,7 +20,6 @@ import { Stack } from './RoutesPage.style.js';
19
20
  export const RoutesPage: React.FC<BoxProps> = () => {
20
21
  const { navigate } = useNavigateBack();
21
22
  const setExecutableRoute = useSetExecutableRoute();
22
- const headerStoreContext = useHeaderStoreContext();
23
23
  const {
24
24
  routes,
25
25
  isLoading,
@@ -33,6 +33,24 @@ export const RoutesPage: React.FC<BoxProps> = () => {
33
33
  const [toAddress] = useFieldValues('toAddress');
34
34
  const { requiredToAddress } = useToAddressRequirements();
35
35
 
36
+ const { t } = useTranslation();
37
+
38
+ const headerAction = useMemo(
39
+ () => (
40
+ <ProgressToNextUpdate
41
+ updatedAt={dataUpdatedAt || new Date().getTime()}
42
+ timeToUpdate={refetchTime}
43
+ isLoading={isFetching}
44
+ onClick={() => refetch()}
45
+ sx={{ marginRight: -1 }}
46
+ size="medium"
47
+ />
48
+ ),
49
+ [dataUpdatedAt, isFetching, refetch, refetchTime],
50
+ );
51
+
52
+ useHeader(t(`header.youGet`), headerAction);
53
+
36
54
  const handleRouteClick = (route: Route) => {
37
55
  setExecutableRoute(route);
38
56
  navigate(navigationRoutes.transactionExecution, {
@@ -40,21 +58,6 @@ export const RoutesPage: React.FC<BoxProps> = () => {
40
58
  });
41
59
  };
42
60
 
43
- useEffect(() => {
44
- return headerStoreContext
45
- .getState()
46
- .setAction(
47
- <ProgressToNextUpdate
48
- updatedAt={dataUpdatedAt || new Date().getTime()}
49
- timeToUpdate={refetchTime}
50
- isLoading={isFetching}
51
- onClick={() => refetch()}
52
- sx={{ marginRight: -1 }}
53
- size="medium"
54
- />,
55
- );
56
- }, [dataUpdatedAt, headerStoreContext, isFetching, refetch, refetchTime]);
57
-
58
61
  const routeNotFound = !routes?.length && !isLoading && !isFetching;
59
62
 
60
63
  const toAddressUnsatisfied = routes?.[0] && requiredToAddress && !toAddress;
@@ -1,10 +1,12 @@
1
1
  import type { ExtendedChain } from '@lifi/sdk';
2
2
  import { Avatar, List, ListItemAvatar } from '@mui/material';
3
+ import { useTranslation } from 'react-i18next';
3
4
  import { useChainSelect } from '../../components/ChainSelect/useChainSelect.js';
4
5
  import { ListItemButton } from '../../components/ListItemButton.js';
5
6
  import { ListItemText } from '../../components/ListItemText.js';
6
7
  import { PageContainer } from '../../components/PageContainer.js';
7
8
  import { useTokenSelect } from '../../components/TokenList/useTokenSelect.js';
9
+ import { useHeader } from '../../hooks/useHeader.js';
8
10
  import { useNavigateBack } from '../../hooks/useNavigateBack.js';
9
11
  import type { SelectChainPageProps } from './types.js';
10
12
 
@@ -16,6 +18,9 @@ export const SelectChainPage: React.FC<SelectChainPageProps> = ({
16
18
  const { chains, setCurrentChain } = useChainSelect(formType);
17
19
  const selectToken = useTokenSelect(formType, navigateBack);
18
20
 
21
+ const { t } = useTranslation();
22
+ useHeader(t('header.selectChain'));
23
+
19
24
  const handleClick = async (chain: ExtendedChain) => {
20
25
  if (selectNativeToken) {
21
26
  selectToken(chain.nativeToken.address, chain.id);
@@ -13,14 +13,14 @@ import {
13
13
  useTheme,
14
14
  } from '@mui/material';
15
15
  import type { MouseEventHandler } from 'react';
16
- import { useEffect } from 'react';
16
+ import { useMemo } from 'react';
17
17
  import { useTranslation } from 'react-i18next';
18
18
  import { shallow } from 'zustand/shallow';
19
19
  import { ListItemText } from '../components/ListItemText.js';
20
20
  import { PageContainer } from '../components/PageContainer.js';
21
21
  import { SettingsListItemButton } from '../components/SettingsListItemButton.js';
22
+ import { useHeader } from '../hooks/useHeader.js';
22
23
  import { useTools } from '../hooks/useTools.js';
23
- import { useHeaderStoreContext } from '../stores/header/useHeaderStore.js';
24
24
  import { useSettingsStore } from '../stores/settings/useSettingsStore.js';
25
25
 
26
26
  interface SelectAllCheckboxProps {
@@ -74,24 +74,26 @@ export const SelectEnabledToolsPage: React.FC<{
74
74
  ],
75
75
  shallow,
76
76
  );
77
- const headerStoreContext = useHeaderStoreContext();
77
+
78
+ const { t } = useTranslation();
79
+
80
+ const headerAction = useMemo(
81
+ () => (
82
+ <SelectAllCheckbox
83
+ allCheckboxesSelected={!disabledTools.length}
84
+ anyCheckboxesSelected={Boolean(disabledTools.length)}
85
+ onClick={() => toggleTools(type)}
86
+ />
87
+ ),
88
+ [disabledTools.length, toggleTools, type],
89
+ );
90
+
91
+ useHeader(t(`settings.enabled${type}`), headerAction);
78
92
 
79
93
  const handleClick = (key: string) => {
80
94
  setToolValue(type, key, !enabledTools[key]);
81
95
  };
82
96
 
83
- useEffect(() => {
84
- return headerStoreContext
85
- .getState()
86
- .setAction(
87
- <SelectAllCheckbox
88
- allCheckboxesSelected={!disabledTools.length}
89
- anyCheckboxesSelected={Boolean(disabledTools.length)}
90
- onClick={() => toggleTools(type)}
91
- />,
92
- );
93
- }, [disabledTools.length, headerStoreContext, toggleTools, type]);
94
-
95
97
  return (
96
98
  <PageContainer disableGutters>
97
99
  <List
@@ -1,13 +1,16 @@
1
1
  import { Box } from '@mui/material';
2
2
  import type { FC } from 'react';
3
3
  import { useLayoutEffect, useRef, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
4
5
  import { ChainSelect } from '../../components/ChainSelect/ChainSelect.js';
5
6
  import { PageContainer } from '../../components/PageContainer.js';
6
7
  import { TokenList } from '../../components/TokenList/TokenList.js';
7
8
  import { useContentHeight } from '../../hooks/useContentHeight.js';
9
+ import { useHeader } from '../../hooks/useHeader.js';
8
10
  import { useNavigateBack } from '../../hooks/useNavigateBack.js';
9
11
  import { useScrollableOverflowHidden } from '../../hooks/useScrollableContainer.js';
10
12
  import { useSwapOnly } from '../../hooks/useSwapOnly.js';
13
+ import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
11
14
  import type { FormTypeProps } from '../../stores/form/types.js';
12
15
  import { SearchTokenInput } from './SearchTokenInput.js';
13
16
 
@@ -21,6 +24,17 @@ export const SelectTokenPage: FC<FormTypeProps> = ({ formType }) => {
21
24
  const [tokenListHeight, setTokenListHeight] = useState(0);
22
25
  const swapOnly = useSwapOnly();
23
26
 
27
+ const { subvariant } = useWidgetConfig();
28
+ const { t } = useTranslation();
29
+ const title =
30
+ formType === 'from'
31
+ ? subvariant === 'custom'
32
+ ? t(`header.payWith`)
33
+ : t(`header.from`)
34
+ : t(`header.to`);
35
+
36
+ useHeader(title);
37
+
24
38
  useLayoutEffect(() => {
25
39
  setTokenListHeight(
26
40
  Math.max(
@@ -18,6 +18,7 @@ import type { Connector } from 'wagmi';
18
18
  import { useConnect, useAccount as useWagmiAccount } from 'wagmi';
19
19
  import { Dialog } from '../../components/Dialog.js';
20
20
  import { PageContainer } from '../../components/PageContainer.js';
21
+ import { useHeader } from '../../hooks/useHeader.js';
21
22
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
22
23
  import { isItemAllowed } from '../../utils/item.js';
23
24
  import { EVMListItemButton } from './EVMListItemButton.js';
@@ -35,6 +36,8 @@ export const SelectWalletPage = () => {
35
36
  }>({ show: false });
36
37
  const { wallets: solanaWallets } = useWallet();
37
38
 
39
+ useHeader(t(`header.selectWallet`));
40
+
38
41
  const isDesktopView = useMediaQuery((theme: Theme) =>
39
42
  theme.breakpoints.up('sm'),
40
43
  );
@@ -15,6 +15,7 @@ import { ListItemButton } from '../../components/ListItem//ListItemButton.js';
15
15
  import { ListItem } from '../../components/ListItem/ListItem.js';
16
16
  import { Menu } from '../../components/Menu.js';
17
17
  import { useChains } from '../../hooks/useChains.js';
18
+ import { useHeader } from '../../hooks/useHeader.js';
18
19
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
19
20
  import type { Bookmark } from '../../stores/bookmarks/types.js';
20
21
  import { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js';
@@ -46,6 +47,8 @@ export const BookmarksPage = () => {
46
47
  const { setFieldValue } = useFieldActions();
47
48
  const { setSendToWallet } = useSendToWalletActions();
48
49
 
50
+ useHeader(t(`header.bookmarkedWallets`));
51
+
49
52
  const handleAddBookmark = () => {
50
53
  bookmarkAddressSheetRef.current?.open();
51
54
  };