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

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 (147) hide show
  1. package/_esm/components/AlertMessage/AlertMessage.d.ts +2 -2
  2. package/_esm/components/AlertMessage/AlertMessage.js +1 -1
  3. package/_esm/components/AlertMessage/AlertMessage.js.map +1 -1
  4. package/_esm/components/BaseTransactionButton/BaseTransactionButton.js +1 -1
  5. package/_esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
  6. package/_esm/components/Card/CardLabel.js +27 -23
  7. package/_esm/components/Card/CardLabel.js.map +1 -1
  8. package/_esm/components/Card/InputCard.d.ts +1 -1
  9. package/_esm/components/ChainSelect/ChainSelect.js +10 -3
  10. package/_esm/components/ChainSelect/ChainSelect.js.map +1 -1
  11. package/_esm/components/GasMessage/FundsSufficiencyMessage.js +2 -12
  12. package/_esm/components/GasMessage/FundsSufficiencyMessage.js.map +1 -1
  13. package/_esm/components/Header/EVMDisconnectIconButton.d.ts +1 -1
  14. package/_esm/components/Routes/RoutesExpanded.js +14 -4
  15. package/_esm/components/Routes/RoutesExpanded.js.map +1 -1
  16. package/_esm/components/Select.d.ts +1 -3
  17. package/_esm/components/SelectTokenButton/SelectTokenButton.style.js +4 -0
  18. package/_esm/components/SelectTokenButton/SelectTokenButton.style.js.map +1 -1
  19. package/_esm/components/ToAddressRequiredMessage.d.ts +8 -0
  20. package/_esm/components/ToAddressRequiredMessage.js +15 -0
  21. package/_esm/components/ToAddressRequiredMessage.js.map +1 -0
  22. package/_esm/components/TokenList/useTokenSelect.js +17 -3
  23. package/_esm/components/TokenList/useTokenSelect.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/useGasRefuel.js +1 -0
  27. package/_esm/hooks/useGasRefuel.js.map +1 -1
  28. package/_esm/hooks/useRoutes.d.ts +2 -0
  29. package/_esm/hooks/useRoutes.js +10 -10
  30. package/_esm/hooks/useRoutes.js.map +1 -1
  31. package/_esm/hooks/useTransactionHistory.js +2 -2
  32. package/_esm/hooks/useTransactionHistory.js.map +1 -1
  33. package/_esm/i18n/bn.json +29 -28
  34. package/_esm/i18n/de.json +31 -30
  35. package/_esm/i18n/en.json +1 -0
  36. package/_esm/i18n/es.json +30 -29
  37. package/_esm/i18n/fr.json +44 -43
  38. package/_esm/i18n/hi.json +23 -22
  39. package/_esm/i18n/id.json +30 -29
  40. package/_esm/i18n/it.json +30 -29
  41. package/_esm/i18n/ko.json +31 -30
  42. package/_esm/i18n/pt.json +30 -29
  43. package/_esm/i18n/th.json +30 -29
  44. package/_esm/i18n/tr.json +50 -49
  45. package/_esm/i18n/uk.json +29 -28
  46. package/_esm/i18n/vi.json +30 -29
  47. package/_esm/i18n/zh.json +47 -46
  48. package/_esm/index.d.ts +3 -0
  49. package/_esm/index.js +3 -0
  50. package/_esm/index.js.map +1 -1
  51. package/_esm/pages/MainPage/{MainGasMessage.d.ts → MainMessages.d.ts} +1 -1
  52. package/_esm/pages/MainPage/MainMessages.js +10 -0
  53. package/_esm/pages/MainPage/MainMessages.js.map +1 -0
  54. package/_esm/pages/MainPage/MainPage.js +2 -2
  55. package/_esm/pages/MainPage/MainPage.js.map +1 -1
  56. package/_esm/pages/RoutesPage/RoutesPage.js +10 -2
  57. package/_esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  58. package/_esm/pages/SendToWallet/SendToWalletPage.style.d.ts +2 -2
  59. package/_esm/stores/chains/ChainOrderStore.d.ts +1 -1
  60. package/_esm/stores/chains/ChainOrderStore.js +4 -7
  61. package/_esm/stores/chains/ChainOrderStore.js.map +1 -1
  62. package/_esm/stores/chains/createChainOrderStore.d.ts +1 -1
  63. package/_esm/stores/chains/createChainOrderStore.js +1 -1
  64. package/_esm/stores/chains/createChainOrderStore.js.map +1 -1
  65. package/_esm/stores/form/FormStore.js +2 -2
  66. package/_esm/stores/form/FormStore.js.map +1 -1
  67. package/_esm/stores/form/FormUpdater.d.ts +3 -3
  68. package/_esm/stores/form/FormUpdater.js +7 -5
  69. package/_esm/stores/form/FormUpdater.js.map +1 -1
  70. package/_esm/stores/header/useHeaderStore.d.ts +1 -1
  71. package/_esm/stores/header/useHeaderStore.js +4 -7
  72. package/_esm/stores/header/useHeaderStore.js.map +1 -1
  73. package/_esm/stores/routes/RouteExecutionStore.d.ts +1 -1
  74. package/_esm/stores/routes/RouteExecutionStore.js +4 -7
  75. package/_esm/stores/routes/RouteExecutionStore.js.map +1 -1
  76. package/_esm/stores/settings/useAppearance.d.ts +4 -1
  77. package/_esm/stores/settings/useSplitSubvariantStore.d.ts +1 -1
  78. package/_esm/stores/settings/useSplitSubvariantStore.js +4 -7
  79. package/_esm/stores/settings/useSplitSubvariantStore.js.map +1 -1
  80. package/_esm/themes/azureLight.d.ts +2 -0
  81. package/_esm/themes/azureLight.js +45 -0
  82. package/_esm/themes/azureLight.js.map +1 -0
  83. package/_esm/themes/createTheme.js +1 -44
  84. package/_esm/themes/createTheme.js.map +1 -1
  85. package/_esm/themes/palettes.d.ts +50 -0
  86. package/_esm/themes/palettes.js +51 -0
  87. package/_esm/themes/palettes.js.map +1 -0
  88. package/_esm/themes/watermelonLight.d.ts +2 -0
  89. package/_esm/themes/watermelonLight.js +63 -0
  90. package/_esm/themes/watermelonLight.js.map +1 -0
  91. package/_esm/themes/windows95.js +7 -4
  92. package/_esm/themes/windows95.js.map +1 -1
  93. package/_esm/types/widget.d.ts +0 -5
  94. package/_esm/types/widget.js.map +1 -1
  95. package/_esm/utils/colors.d.ts +11 -0
  96. package/_esm/utils/colors.js +25 -1
  97. package/_esm/utils/colors.js.map +1 -1
  98. package/components/AlertMessage/AlertMessage.tsx +3 -3
  99. package/components/BaseTransactionButton/BaseTransactionButton.tsx +1 -1
  100. package/components/Card/CardLabel.tsx +42 -29
  101. package/components/ChainSelect/ChainSelect.tsx +34 -26
  102. package/components/GasMessage/FundsSufficiencyMessage.tsx +7 -13
  103. package/components/Routes/RoutesExpanded.tsx +17 -3
  104. package/components/SelectTokenButton/SelectTokenButton.style.tsx +4 -0
  105. package/components/ToAddressRequiredMessage.tsx +38 -0
  106. package/components/TokenList/useTokenSelect.ts +20 -3
  107. package/config/version.ts +1 -1
  108. package/hooks/useGasRefuel.ts +1 -0
  109. package/hooks/useRoutes.ts +12 -11
  110. package/hooks/useTransactionHistory.ts +2 -2
  111. package/i18n/bn.json +29 -28
  112. package/i18n/de.json +31 -30
  113. package/i18n/en.json +1 -0
  114. package/i18n/es.json +30 -29
  115. package/i18n/fr.json +44 -43
  116. package/i18n/hi.json +23 -22
  117. package/i18n/id.json +30 -29
  118. package/i18n/it.json +30 -29
  119. package/i18n/ko.json +31 -30
  120. package/i18n/pt.json +30 -29
  121. package/i18n/th.json +30 -29
  122. package/i18n/tr.json +50 -49
  123. package/i18n/uk.json +29 -28
  124. package/i18n/vi.json +30 -29
  125. package/i18n/zh.json +47 -46
  126. package/index.ts +3 -0
  127. package/package.json +14 -14
  128. package/pages/MainPage/MainMessages.tsx +17 -0
  129. package/pages/MainPage/MainPage.tsx +2 -2
  130. package/pages/RoutesPage/RoutesPage.tsx +21 -3
  131. package/stores/chains/ChainOrderStore.tsx +8 -13
  132. package/stores/chains/createChainOrderStore.ts +1 -1
  133. package/stores/form/FormStore.tsx +2 -1
  134. package/stores/form/FormUpdater.tsx +8 -10
  135. package/stores/header/useHeaderStore.tsx +5 -10
  136. package/stores/routes/RouteExecutionStore.tsx +8 -13
  137. package/stores/settings/useSplitSubvariantStore.tsx +7 -12
  138. package/themes/azureLight.ts +46 -0
  139. package/themes/createTheme.ts +1 -47
  140. package/themes/palettes.ts +52 -0
  141. package/themes/watermelonLight.ts +66 -0
  142. package/themes/windows95.ts +7 -4
  143. package/types/widget.ts +0 -5
  144. package/utils/colors.ts +37 -1
  145. package/_esm/pages/MainPage/MainGasMessage.js +0 -9
  146. package/_esm/pages/MainPage/MainGasMessage.js.map +0 -1
  147. package/pages/MainPage/MainGasMessage.tsx +0 -11
@@ -1,50 +1,63 @@
1
1
  import {
2
2
  Box,
3
3
  Typography,
4
- alpha,
5
4
  getContrastRatio,
6
5
  lighten,
7
6
  styled,
8
7
  } from '@mui/material';
8
+ import { blend } from '../../utils/colors.js';
9
9
 
10
10
  export const CardLabel = styled(Box, {
11
11
  shouldForwardProp: (prop) => prop !== 'type',
12
- })<{ type?: 'active' | 'insurance' | 'insurance-icon' }>(({ theme, type }) => ({
13
- backgroundColor:
12
+ })<{ type?: 'active' | 'insurance' | 'insurance-icon' }>(({ theme, type }) => {
13
+ const backgroundColor =
14
14
  type === 'active'
15
15
  ? theme.palette.mode === 'light'
16
16
  ? theme.palette.secondary.main
17
- : alpha(theme.palette.secondary.main, 0.8)
17
+ : blend(
18
+ theme.palette.background.paper,
19
+ theme.palette.secondary.main,
20
+ 0.8,
21
+ )
18
22
  : type?.includes('insurance')
19
- ? alpha(
23
+ ? blend(
24
+ theme.palette.background.paper,
20
25
  theme.palette.success.main,
21
26
  theme.palette.mode === 'light' ? 0.12 : 0.24,
22
27
  )
23
28
  : theme.palette.mode === 'light'
24
- ? alpha(theme.palette.common.black, 0.12)
25
- : alpha(theme.palette.common.white, 0.16),
26
- borderRadius: theme.shape.borderRadius,
27
- color: type?.includes('insurance')
28
- ? lighten(
29
- theme.palette.success.main,
30
- theme.palette.mode === 'light' ? 0 : 0.24,
31
- )
32
- : getContrastRatio(
33
- theme.palette.common.white,
34
- alpha(theme.palette.secondary.main, 0.08),
35
- ) >= 3
36
- ? theme.palette.common.white
37
- : theme.palette.common.black,
38
- padding: type === 'insurance' ? theme.spacing(0, 1.5) : 0,
39
- display: 'flex',
40
- alignItems: 'center',
41
- justifyContent: 'center',
42
- height: 24,
43
- minWidth: 24,
44
- userSelect: 'none',
45
- fontSize: '1rem',
46
- marginRight: theme.spacing(1),
47
- }));
29
+ ? blend(
30
+ theme.palette.background.paper,
31
+ theme.palette.common.black,
32
+ 0.12,
33
+ )
34
+ : blend(
35
+ theme.palette.background.paper,
36
+ theme.palette.common.white,
37
+ 0.16,
38
+ );
39
+ return {
40
+ backgroundColor,
41
+ borderRadius: theme.shape.borderRadius,
42
+ color: type?.includes('insurance')
43
+ ? lighten(
44
+ theme.palette.success.main,
45
+ theme.palette.mode === 'light' ? 0 : 0.24,
46
+ )
47
+ : getContrastRatio(theme.palette.common.white, backgroundColor) >= 3
48
+ ? theme.palette.common.white
49
+ : theme.palette.common.black,
50
+ padding: type === 'insurance' ? theme.spacing(0, 1.5) : 0,
51
+ display: 'flex',
52
+ alignItems: 'center',
53
+ justifyContent: 'center',
54
+ height: 24,
55
+ minWidth: 24,
56
+ userSelect: 'none',
57
+ fontSize: '1rem',
58
+ marginRight: theme.spacing(1),
59
+ };
60
+ });
48
61
 
49
62
  export const CardLabelTypography = styled(Typography, {
50
63
  shouldForwardProp: (prop) => prop !== 'type',
@@ -38,12 +38,18 @@ export const ChainSelect = ({ formType }: FormTypeProps) => {
38
38
  navigate(navigationRoutes[`${formType}Chain`]);
39
39
  };
40
40
 
41
- const chainsToHide = (chains?.length ?? 0) - maxChainToOrder;
41
+ // We check if we can accommodate all the chains on the grid
42
+ // If there are more chains we slice the last one to show the number of hidden chains
43
+ const chainsToHide =
44
+ chains?.length === maxChainToOrder
45
+ ? 0
46
+ : (chains?.length ?? 0) - (maxChainToOrder - 1);
47
+ const sliceValue = chainsToHide > 0 ? -1 : maxChainToOrder;
42
48
 
43
49
  return (
44
50
  <ChainContainer>
45
51
  {isLoading
46
- ? Array.from({ length: maxChainToOrder + 1 }).map((_, index) => (
52
+ ? Array.from({ length: maxChainToOrder }).map((_, index) => (
47
53
  <Skeleton
48
54
  key={index}
49
55
  variant="rectangular"
@@ -52,32 +58,34 @@ export const ChainSelect = ({ formType }: FormTypeProps) => {
52
58
  sx={{ borderRadius: 1 }}
53
59
  />
54
60
  ))
55
- : getChains().map((chain: EVMChain) => (
56
- <Tooltip
57
- key={chain.id}
58
- title={chain.name}
59
- placement="top"
60
- enterDelay={400}
61
- enterNextDelay={100}
62
- disableInteractive
63
- arrow
64
- >
65
- <ChainCard
66
- component="button"
67
- onClick={() => setCurrentChain(chain.id)}
68
- type={chainId === chain.id ? 'selected' : 'default'}
69
- selectionColor="primary"
61
+ : getChains()
62
+ .slice(0, sliceValue)
63
+ .map((chain: EVMChain) => (
64
+ <Tooltip
65
+ key={chain.id}
66
+ title={chain.name}
67
+ placement="top"
68
+ enterDelay={400}
69
+ enterNextDelay={100}
70
+ disableInteractive
71
+ arrow
70
72
  >
71
- <Avatar
72
- src={chain.logoURI}
73
- alt={chain.key}
74
- sx={{ width: 40, height: 40 }}
73
+ <ChainCard
74
+ component="button"
75
+ onClick={() => setCurrentChain(chain.id)}
76
+ type={chainId === chain.id ? 'selected' : 'default'}
77
+ selectionColor="primary"
75
78
  >
76
- {chain.name[0]}
77
- </Avatar>
78
- </ChainCard>
79
- </Tooltip>
80
- ))}
79
+ <Avatar
80
+ src={chain.logoURI}
81
+ alt={chain.key}
82
+ sx={{ width: 40, height: 40 }}
83
+ >
84
+ {chain.name[0]}
85
+ </Avatar>
86
+ </ChainCard>
87
+ </Tooltip>
88
+ ))}
81
89
  {chainsToHide > 0 ? (
82
90
  <ChainCard component="button" onClick={showAllChains}>
83
91
  <Box
@@ -1,26 +1,20 @@
1
1
  import { WarningRounded } from '@mui/icons-material';
2
- import { Typography, styled } from '@mui/material';
2
+ import { Typography } from '@mui/material';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { AlertMessage } from '../AlertMessage/AlertMessage.js';
5
5
 
6
- // TODO: some of the styling currently used here doesn't align with usage in other places
7
- // We might want to consider removing the padding and color here?
8
- const AlertTitle = styled(Typography)(({ theme }) => {
9
- return {
10
- ...theme.typography.body2,
11
- paddingRight: theme.spacing(1),
12
- paddingLeft: theme.spacing(1),
13
- color: theme.palette.text.primary,
14
- };
15
- });
16
6
  export const FundsSufficiencyMessage = () => {
17
7
  const { t } = useTranslation();
18
8
  return (
19
9
  <AlertMessage
20
10
  severity="warning"
21
11
  icon={<WarningRounded />}
22
- title={<AlertTitle>{t(`warning.message.insufficientFunds`)}</AlertTitle>}
23
- isMultilineTitle
12
+ title={
13
+ <Typography variant="body2" px={1} color="text.primary">
14
+ {t(`warning.message.insufficientFunds`)}
15
+ </Typography>
16
+ }
17
+ multilineTitle
24
18
  />
25
19
  );
26
20
  };
@@ -5,9 +5,12 @@ import { useEffect, useRef } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import type { RouteObject } from 'react-router-dom';
7
7
  import { useRoutes as useDOMRoutes, useNavigate } from 'react-router-dom';
8
+ import { useAccount } from '../../hooks/useAccount.js';
8
9
  import { useRoutes } from '../../hooks/useRoutes.js';
10
+ import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
9
11
  import { useWidgetEvents } from '../../hooks/useWidgetEvents.js';
10
12
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
13
+ import { useFieldValues } from '../../stores/form/useFieldValues.js';
11
14
  import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';
12
15
  import { WidgetEvent } from '../../types/events.js';
13
16
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
@@ -69,7 +72,11 @@ export const RoutesExpandedElement = () => {
69
72
  dataUpdatedAt,
70
73
  refetchTime,
71
74
  refetch,
75
+ fromChain,
72
76
  } = useRoutes();
77
+ const { account } = useAccount({ chainType: fromChain?.chainType });
78
+ const [toAddress] = useFieldValues('toAddress');
79
+ const { requiredToAddress } = useToAddressRequirements();
73
80
 
74
81
  const handleRouteClick = (route: Route) => {
75
82
  setExecutableRoute(route);
@@ -84,11 +91,11 @@ export const RoutesExpandedElement = () => {
84
91
  };
85
92
 
86
93
  // We cache routes results in ref for a better exit animation
87
- if (routesRef.current && !routes?.length) {
94
+ if (routesRef.current && !routes) {
88
95
  routesActiveRef.current = false;
89
96
  } else {
90
97
  routesRef.current = routes;
91
- routesActiveRef.current = Boolean(routes?.length);
98
+ routesActiveRef.current = Boolean(routes);
92
99
  }
93
100
 
94
101
  const currentRoute = routesRef.current?.[0];
@@ -99,6 +106,9 @@ export const RoutesExpandedElement = () => {
99
106
 
100
107
  const routeNotFound = !currentRoute && !isLoading && !isFetching && expanded;
101
108
 
109
+ const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress;
110
+ const allowInteraction = account.isConnected && !toAddressUnsatisfied;
111
+
102
112
  useEffect(() => {
103
113
  emitter.emit(WidgetEvent.WidgetExpanded, expanded);
104
114
  }, [emitter, expanded]);
@@ -140,7 +150,11 @@ export const RoutesExpandedElement = () => {
140
150
  <RouteCard
141
151
  key={index}
142
152
  route={route}
143
- onClick={() => handleRouteClick(route)}
153
+ onClick={
154
+ allowInteraction
155
+ ? () => handleRouteClick(route)
156
+ : undefined
157
+ }
144
158
  active={index === 0}
145
159
  expanded={routesRef.current?.length === 1}
146
160
  />
@@ -64,6 +64,10 @@ export const CardContent = styled(MuiCardContent, {
64
64
  const vertical = compact ? '50%' : direction;
65
65
  return {
66
66
  padding: 0,
67
+ transition: theme.transitions.create(['background-color'], {
68
+ duration: theme.transitions.duration.enteringScreen,
69
+ easing: theme.transitions.easing.easeOut,
70
+ }),
67
71
  '&:last-child': {
68
72
  paddingBottom: 0,
69
73
  },
@@ -0,0 +1,38 @@
1
+ import type { Route } from '@lifi/sdk';
2
+ import { Wallet } from '@mui/icons-material';
3
+ import type { BoxProps } from '@mui/material';
4
+ import { Box, Collapse, Typography } from '@mui/material';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { useToAddressRequirements } from '../hooks/useToAddressRequirements.js';
7
+ import { useFieldValues } from '../stores/form/useFieldValues.js';
8
+ import { AlertMessage } from './AlertMessage/AlertMessage.js';
9
+
10
+ interface ToAddressRequiredMessageProps extends BoxProps {
11
+ route?: Route;
12
+ }
13
+
14
+ export const ToAddressRequiredMessage: React.FC<
15
+ ToAddressRequiredMessageProps
16
+ > = ({ route, ...props }) => {
17
+ const { t } = useTranslation();
18
+ const [toAddress] = useFieldValues('toAddress');
19
+ const { requiredToAddress } = useToAddressRequirements();
20
+
21
+ const showMessage = route && requiredToAddress && !toAddress;
22
+
23
+ return (
24
+ <Collapse timeout={225} in={showMessage} unmountOnExit mountOnEnter>
25
+ <Box {...props}>
26
+ <AlertMessage
27
+ title={
28
+ <Typography variant="body2" px={1} color="text.primary">
29
+ {t('info.message.toAddressIsRequired')}
30
+ </Typography>
31
+ }
32
+ icon={<Wallet />}
33
+ multilineTitle
34
+ />
35
+ </Box>
36
+ </Collapse>
37
+ );
38
+ };
@@ -1,6 +1,7 @@
1
1
  import { useCallback } from 'react';
2
2
  import { useWidgetEvents } from '../../hooks/useWidgetEvents.js';
3
3
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
4
+ import { useChainOrderStoreContext } from '../../stores/chains/ChainOrderStore.js';
4
5
  import type { FormType } from '../../stores/form/types.js';
5
6
  import { FormKeyHelper } from '../../stores/form/types.js';
6
7
  import { useFieldActions } from '../../stores/form/useFieldActions.js';
@@ -8,11 +9,12 @@ import { useFieldController } from '../../stores/form/useFieldController.js';
8
9
  import { WidgetEvent } from '../../types/events.js';
9
10
 
10
11
  export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
11
- const tokenKey = FormKeyHelper.getTokenKey(formType);
12
- const { onChange } = useFieldController({ name: tokenKey });
13
- const { setFieldValue, getFieldValues } = useFieldActions();
14
12
  const { subvariant } = useWidgetConfig();
15
13
  const emitter = useWidgetEvents();
14
+ const { setFieldValue, getFieldValues } = useFieldActions();
15
+ const tokenKey = FormKeyHelper.getTokenKey(formType);
16
+ const { onChange } = useFieldController({ name: tokenKey });
17
+ const chainOrderStore = useChainOrderStoreContext();
16
18
 
17
19
  return useCallback(
18
20
  (tokenAddress: string, chainId?: number) => {
@@ -41,6 +43,20 @@ export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
41
43
  });
42
44
  }
43
45
 
46
+ // Check if the selected source chain matches any chain on the destination chain selection view (chainOrder array).
47
+ // If a match exists and the destination token is not selected, update the destination chain to match the source.
48
+ if (
49
+ formType === 'from' &&
50
+ !selectedOppositeToken &&
51
+ selectedChainId &&
52
+ chainOrderStore.getState().chainOrder.to.includes(selectedChainId)
53
+ ) {
54
+ setFieldValue(FormKeyHelper.getChainKey('to'), selectedChainId, {
55
+ isDirty: true,
56
+ isTouched: true,
57
+ });
58
+ }
59
+
44
60
  const eventToEmit =
45
61
  formType === 'from'
46
62
  ? WidgetEvent.SourceChainTokenSelected
@@ -56,6 +72,7 @@ export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
56
72
  onClick?.();
57
73
  },
58
74
  [
75
+ chainOrderStore,
59
76
  emitter,
60
77
  formType,
61
78
  getFieldValues,
package/config/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget';
2
- export const version = '3.0.0-alpha.35';
2
+ export const version = '3.0.0-alpha.37';
@@ -39,6 +39,7 @@ export const useGasRefuel = () => {
39
39
  // If a user runs out of gas, he can't send a source chain transaction.
40
40
  fromChainId === toChainId ||
41
41
  !gasRecommendation?.available ||
42
+ !gasRecommendation?.recommended ||
42
43
  !nativeToken ||
43
44
  !isChainTypeSatisfied
44
45
  ) {
@@ -70,6 +70,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
70
70
  const contractCallQuoteEnabled: boolean =
71
71
  subvariant === 'custom' ? Boolean(contractCalls && account.address) : true;
72
72
 
73
+ // When we bridge between ecosystems we need to be sure toAddress is set and has the same chainType as toChain
73
74
  // If toAddress is set, it must have the same chainType as toChain
74
75
  const hasToAddressAndChainTypeSatisfied: boolean =
75
76
  !!toChain &&
@@ -79,11 +80,9 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
79
80
  const isToAddressSatisfied = toAddress
80
81
  ? hasToAddressAndChainTypeSatisfied
81
82
  : true;
82
- // When we bridge between ecosystems we need to be sure toAddress is set and has the same chainType as toChain
83
- const isChainTypeSatisfied =
84
- fromChain && toChain && fromChain.chainType !== toChain.chainType
85
- ? hasToAddressAndChainTypeSatisfied
86
- : true;
83
+
84
+ // toAddress might be an empty string, but we need to pass undefined if there is no value
85
+ const toWalletAddress = toAddress || undefined;
87
86
 
88
87
  const isEnabled =
89
88
  Boolean(Number(fromChainId)) &&
@@ -93,7 +92,6 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
93
92
  !Number.isNaN(slippage) &&
94
93
  hasAmount &&
95
94
  isToAddressSatisfied &&
96
- isChainTypeSatisfied &&
97
95
  contractCallQuoteEnabled;
98
96
 
99
97
  // Some values should be strictly typed and isEnabled ensures that
@@ -103,7 +101,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
103
101
  fromChainId as number,
104
102
  fromToken?.address as string,
105
103
  fromTokenAmount,
106
- toAddress,
104
+ toWalletAddress,
107
105
  toChainId as number,
108
106
  toToken?.address as string,
109
107
  toTokenAmount,
@@ -150,7 +148,6 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
150
148
  ],
151
149
  signal,
152
150
  }) => {
153
- const toWalletAddress = toAddress || fromAddress;
154
151
  const fromAmount = parseUnits(
155
152
  fromTokenAmount,
156
153
  fromToken!.decimals,
@@ -198,7 +195,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
198
195
  : undefined,
199
196
  allowBridges: allowedBridges,
200
197
  allowExchanges: allowedExchanges,
201
- toFallbackAddress: toWalletAddress,
198
+ toFallbackAddress: toAddress,
202
199
  slippage: formattedSlippage,
203
200
  },
204
201
  { signal },
@@ -235,7 +232,9 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
235
232
  toAmount: toTokenAmount,
236
233
  toAmountMin: toTokenAmount,
237
234
  toToken: toToken!,
238
- toAddress: toWalletAddress,
235
+ toAddress:
236
+ contractCallQuote.action.toAddress ||
237
+ contractCallQuote.action.fromAddress,
239
238
  gasCostUSD: contractCallQuote.estimate.gasCosts?.[0].amountUSD,
240
239
  steps: [contractCallQuote],
241
240
  insurance: { state: 'NOT_INSURABLE', feeAmountUsd: '0' },
@@ -250,7 +249,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
250
249
  fromAmount,
251
250
  fromChainId,
252
251
  fromTokenAddress,
253
- toAddress: toWalletAddress,
252
+ toAddress,
254
253
  toChainId,
255
254
  toTokenAddress,
256
255
  fromAmountForGas:
@@ -333,5 +332,7 @@ export const useRoutes = ({ insurableRoute }: RoutesProps = {}) => {
333
332
  dataUpdatedAt,
334
333
  refetchTime,
335
334
  refetch,
335
+ fromChain,
336
+ toChain,
336
337
  };
337
338
  };
@@ -20,8 +20,8 @@ export const useTransactionHistory = () => {
20
20
  const response = await getTransactionHistory(
21
21
  {
22
22
  wallet: accountAddress,
23
- fromTimestamp: date.getTime() / 1000,
24
- toTimestamp: Date.now() / 1000,
23
+ fromTimestamp: Math.floor(date.getTime() / 1000),
24
+ toTimestamp: Math.floor(Date.now() / 1000),
25
25
  },
26
26
  { signal },
27
27
  );
package/i18n/bn.json CHANGED
@@ -28,10 +28,7 @@
28
28
  "done": "সম্পন্ন হয়েছে",
29
29
  "exchange": "",
30
30
  "getGas": "গ্যাস পান",
31
- "hide": "গোপন করুন",
32
31
  "learnMore": "আরও জানুন",
33
- "lifiCheckout": "",
34
- "lifiExchange": "",
35
32
  "light": "লাইট",
36
33
  "max": "সর্বোচ্চ",
37
34
  "ok": "ঠিক আছে",
@@ -80,8 +77,9 @@
80
77
  "emptyActiveTransactions": "",
81
78
  "emptyTokenList": "",
82
79
  "emptyTransactionHistory": "",
83
- "routeNotFound": "",
84
- "fundsToExchange": ""
80
+ "fundsToExchange": "",
81
+ "toAddressIsRequired": "",
82
+ "routeNotFound": ""
85
83
  },
86
84
  "title": {
87
85
  "autoRefuel": "গ্যাস পান",
@@ -130,16 +128,15 @@
130
128
  "message": {
131
129
  "allowanceRequired": "",
132
130
  "insufficientFunds": "",
131
+ "remainInYourWallet": "",
133
132
  "signatureRejected": "",
134
133
  "slippageThreshold": "স্লিপেজ সংজ্ঞায়িত থ্রেশহোল্ডের চেয়ে বড়। একটি নতুন উদ্ধৃতি পেতে একটি নতুন রুট অনুরোধ করুন।",
134
+ "transactionCanceled": "",
135
135
  "transactionFailed": "আরও তথ্যের জন্য ব্লক এক্সপ্লোরার চেক করুন।",
136
136
  "transactionNotSent": "",
137
- "transactionCanceled": "",
138
- "remainInYourWallet": "",
139
137
  "unknown": "অনুগ্রহ করে আবার চেষ্টা করুন বা সাপোর্ট এর সাথে যোগাযোগ করুন।"
140
138
  },
141
139
  "title": {
142
- "addressRequired": "",
143
140
  "allowanceRequired": "",
144
141
  "balanceIsTooLow": "ব্যালেন্স খুব কম",
145
142
  "bookmarkAlreadyExists": "",
@@ -156,6 +153,7 @@
156
153
  "transactionUnprepared": "লেনদেন প্রস্তুত করতে অক্ষম",
157
154
  "unknown": "কিছু ভুল হয়েছে",
158
155
  "walletAddressInvalid": "",
156
+ "walletAddressInvalid_chain": "",
159
157
  "walletAddressRequired": "ওয়ালেট ঠিকানা প্রয়োজন।",
160
158
  "walletChainTypeInvalid": ""
161
159
  }
@@ -168,14 +166,16 @@
168
166
  },
169
167
  "numberOfSteps": "সোওয়াপ পদক্ষেপ একটি সংখ্যা. প্রতিটি ধাপে ১-২ টি লেনদেন থাকতে পারে যার জন্য একটি স্বাক্ষর প্রয়োজন।",
170
168
  "progressToNextUpdate": "প্রদর্শিত ডেটা {{value}} সেকেন্ড পরে স্বয়ংক্রিয়ভাবে রিফ্রেশ হবে। ম্যানুয়ালি আপডেট করতে এখানে ক্লিক করুন।",
171
- "recommended": "",
172
169
  "settingsModified": "সেটিংস (পরিবর্তিত)",
173
170
  "selectAll": "",
174
171
  "deselectAll": ""
175
172
  },
176
173
  "main": {
177
- "crossStepDetails": "{{tool}} হয়ে {{from}} থেকে {{to}} পর্যন্ত ব্রিজ",
174
+ "allTokens": "",
175
+ "bridgeStepDetails": "",
176
+ "checkoutStepDetails": "",
178
177
  "currentAmount": "বর্তমান পরিমাণ",
178
+ "depositStepDetails": "",
179
179
  "featuredTokens": "বৈশিষ্ট্যযুক্ত টোকেন",
180
180
  "fees": {
181
181
  "estimated": "",
@@ -189,18 +189,21 @@
189
189
  "fromAmount": "আপনি টাকা পাঠান",
190
190
  "gasCost": "গ্যাস খরচ",
191
191
  "inProgress": "প্রক্রিয়াধীন",
192
- "nftStepDetails": "{{tool}} এর মাধ্যমে এনএফটি কিনুন",
192
+ "myTokens": "",
193
193
  "onChain": "{{chainName}} -এ",
194
- "otherTokens": "অন্যান্য টোকেন",
195
194
  "ownedBy": "মালিক",
195
+ "popularTokens": "",
196
196
  "process": {
197
- "crossChain": {
198
- "actionRequired": "দয়াকরে লেনদেন স্বাক্ষর করুন",
199
- "done": "ব্রিজ লেনদেন নিশ্চিত করা হয়েছে",
200
- "pending": "ব্রিজ লেনদেনের জন্য অপেক্ষা করছে",
201
- "started": "ব্রিজ লেনদেনের প্রস্তুতি"
197
+ "bridge": {
198
+ "actionRequired": "",
199
+ "done": "",
200
+ "pending": "",
201
+ "started": ""
202
+ },
203
+ "checkout": {
204
+ "done": ""
202
205
  },
203
- "nft": {
206
+ "deposit": {
204
207
  "done": ""
205
208
  },
206
209
  "receivingChain": {
@@ -245,13 +248,11 @@
245
248
  "supportId": "সাপোর্ট আইডি",
246
249
  "swapStepDetails": "{{tool}} এর মাধ্যমে {{chain}} এ সোওয়াপ করুন",
247
250
  "tags": {
248
- "cheapest": "সস্তা",
249
- "fastest": "দ্রুত",
251
+ "cheapest": "",
252
+ "fastest": "",
250
253
  "insurable": "বীমাযোগ্য",
251
254
  "insurance": "বীমা",
252
- "insured": "বীমাকৃত",
253
- "recommended": "",
254
- "safest": "নিরাপদ"
255
+ "insured": "বীমাকৃত"
255
256
  },
256
257
  "to": "প্রতি",
257
258
  "tokenOnChain": "{{chainName}} -এ {{tokenSymbol}}",
@@ -276,18 +277,18 @@
276
277
  "title": "গ্যাসের দাম"
277
278
  },
278
279
  "routePriority": "রুট অগ্রাধিকার",
279
- "sendToWalletOption": "",
280
280
  "slippage": "স্লিপেজ",
281
281
  "custom": "",
282
282
  "resetSettings": ""
283
283
  },
284
284
  "sendToWallet": {
285
- "enterAddress": "",
286
- "enterName": "",
285
+ "addBookmark": "",
286
+ "bookmarkWallet": "",
287
287
  "confirmWalletAddress": "",
288
288
  "connectedWallets": "",
289
- "bookmarkWallet": "",
290
- "addBookmark": "",
289
+ "enterAddress_long": "",
290
+ "enterAddress_short": "",
291
+ "enterName": "",
291
292
  "noBookmarkedWallets": "",
292
293
  "noConnectedWallets": "",
293
294
  "noRecentWallets": ""