@lifi/widget 1.25.0 → 1.26.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 (94) hide show
  1. package/cjs/components/ActiveSwaps/ActiveSwapItem.js +6 -3
  2. package/cjs/components/GasSufficiencyMessage/GasSufficiencyMessage.js +1 -1
  3. package/cjs/components/Header/NavigationHeader.js +1 -1
  4. package/cjs/components/Header/WalletHeader.js +1 -1
  5. package/cjs/components/ReverseTokensButton/ReverseTokensButton.style.js +1 -1
  6. package/cjs/components/Step/CircularProgress.d.ts +3 -3
  7. package/cjs/components/Step/CircularProgress.js +10 -9
  8. package/cjs/components/Step/CircularProgress.style.d.ts +12 -3
  9. package/cjs/components/Step/CircularProgress.style.js +26 -10
  10. package/cjs/components/Step/DestinationWalletAddress.d.ts +7 -0
  11. package/cjs/components/Step/DestinationWalletAddress.js +32 -0
  12. package/cjs/components/Step/GasStepProcess.d.ts +5 -0
  13. package/cjs/components/Step/GasStepProcess.js +24 -0
  14. package/cjs/components/Step/Step.d.ts +1 -0
  15. package/cjs/components/Step/Step.js +18 -6
  16. package/cjs/components/Step/StepList.d.ts +3 -0
  17. package/cjs/components/Step/StepList.js +20 -0
  18. package/cjs/components/Step/StepProcess.js +2 -2
  19. package/cjs/components/Step/index.d.ts +1 -0
  20. package/cjs/components/Step/index.js +1 -0
  21. package/cjs/components/SwapButton/SwapButton.js +1 -1
  22. package/cjs/components/SwapRouteCard/SwapRouteNotFoundCard.js +1 -1
  23. package/cjs/components/TokenList/useTokenSelect.js +6 -6
  24. package/cjs/config/sentry.js +1 -1
  25. package/cjs/config/version.d.ts +1 -1
  26. package/cjs/config/version.js +1 -1
  27. package/cjs/hooks/useChains.js +4 -1
  28. package/cjs/hooks/useProcessMessage.js +47 -5
  29. package/cjs/hooks/useRouteExecution.d.ts +8 -2
  30. package/cjs/hooks/useRouteExecution.js +14 -5
  31. package/cjs/hooks/useSwapRoutes.d.ts +2 -2
  32. package/cjs/hooks/useSwapRoutes.js +7 -0
  33. package/cjs/hooks/useTokenBalance.js +2 -2
  34. package/cjs/hooks/useTools.js +2 -0
  35. package/cjs/i18n/en.json +44 -28
  36. package/cjs/pages/SwapDetailsPage/SwapDetailsPage.js +10 -15
  37. package/cjs/pages/SwapHistoryPage/SwapHistoryEmpty.js +1 -1
  38. package/cjs/pages/SwapPage/ExchangeRateBottomSheet.d.ts +15 -0
  39. package/cjs/pages/SwapPage/ExchangeRateBottomSheet.js +71 -0
  40. package/cjs/pages/SwapPage/StatusBottomSheet.js +20 -4
  41. package/cjs/pages/SwapPage/StatusBottomSheet.style.js +4 -4
  42. package/cjs/pages/SwapPage/SwapPage.js +12 -14
  43. package/cjs/pages/SwapPage/TokenValueBottomSheet.js +3 -2
  44. package/cjs/providers/SDKProvider/SDKProvider.js +4 -3
  45. package/cjs/types/widget.d.ts +1 -0
  46. package/cjs/utils/navigationRoutes.js +1 -0
  47. package/components/ActiveSwaps/ActiveSwapItem.js +6 -3
  48. package/components/GasSufficiencyMessage/GasSufficiencyMessage.js +1 -1
  49. package/components/Header/NavigationHeader.js +2 -2
  50. package/components/Header/WalletHeader.js +1 -1
  51. package/components/ReverseTokensButton/ReverseTokensButton.style.js +1 -1
  52. package/components/Step/CircularProgress.d.ts +3 -3
  53. package/components/Step/CircularProgress.js +12 -11
  54. package/components/Step/CircularProgress.style.d.ts +12 -3
  55. package/components/Step/CircularProgress.style.js +27 -11
  56. package/components/Step/DestinationWalletAddress.d.ts +7 -0
  57. package/components/Step/DestinationWalletAddress.js +28 -0
  58. package/components/Step/GasStepProcess.d.ts +5 -0
  59. package/components/Step/GasStepProcess.js +20 -0
  60. package/components/Step/Step.d.ts +1 -0
  61. package/components/Step/Step.js +18 -6
  62. package/components/Step/StepList.d.ts +3 -0
  63. package/components/Step/StepList.js +16 -0
  64. package/components/Step/StepProcess.js +2 -2
  65. package/components/Step/index.d.ts +1 -0
  66. package/components/Step/index.js +1 -0
  67. package/components/SwapButton/SwapButton.js +1 -1
  68. package/components/SwapRouteCard/SwapRouteNotFoundCard.js +1 -1
  69. package/components/TokenList/useTokenSelect.js +6 -6
  70. package/config/sentry.js +1 -1
  71. package/config/version.d.ts +1 -1
  72. package/config/version.js +1 -1
  73. package/hooks/useChains.js +5 -2
  74. package/hooks/useProcessMessage.js +47 -5
  75. package/hooks/useRouteExecution.d.ts +8 -2
  76. package/hooks/useRouteExecution.js +15 -6
  77. package/hooks/useSwapRoutes.d.ts +2 -2
  78. package/hooks/useSwapRoutes.js +7 -0
  79. package/hooks/useTokenBalance.js +2 -2
  80. package/hooks/useTools.js +2 -0
  81. package/i18n/en.json +44 -28
  82. package/package.json +9 -9
  83. package/pages/SwapDetailsPage/SwapDetailsPage.js +14 -19
  84. package/pages/SwapHistoryPage/SwapHistoryEmpty.js +1 -1
  85. package/pages/SwapPage/ExchangeRateBottomSheet.d.ts +15 -0
  86. package/pages/SwapPage/ExchangeRateBottomSheet.js +67 -0
  87. package/pages/SwapPage/StatusBottomSheet.js +22 -6
  88. package/pages/SwapPage/StatusBottomSheet.style.js +4 -4
  89. package/pages/SwapPage/SwapPage.js +15 -17
  90. package/pages/SwapPage/TokenValueBottomSheet.js +3 -2
  91. package/providers/SDKProvider/SDKProvider.js +4 -3
  92. package/tsconfig.cjs.tsbuildinfo +1 -1
  93. package/types/widget.d.ts +1 -0
  94. package/utils/navigationRoutes.js +1 -0
@@ -36,6 +36,7 @@ export interface WidgetConfig {
36
36
  toToken?: string;
37
37
  toAddress?: string;
38
38
  fromAmount?: number | string;
39
+ fee?: number;
39
40
  integrator?: string;
40
41
  slippage?: number;
41
42
  routePriority?: Order;
@@ -20,6 +20,7 @@ exports.navigationRoutesValues = Object.values(exports.navigationRoutes);
20
20
  exports.stickyHeaderRoutes = [
21
21
  exports.navigationRoutes.activeSwaps,
22
22
  exports.navigationRoutes.fromChain,
23
+ exports.navigationRoutes.home,
23
24
  exports.navigationRoutes.selectWallet,
24
25
  exports.navigationRoutes.settings,
25
26
  exports.navigationRoutes.swapDetails,
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ArrowForward as ArrowForwardIcon, Info as InfoIcon, Warning as WarningIcon, } from '@mui/icons-material';
2
+ import { ArrowForward as ArrowForwardIcon, ErrorRounded as ErrorIcon, InfoRounded as InfoIcon } from '@mui/icons-material';
3
3
  import { ListItemAvatar, ListItemText, Typography } from '@mui/material';
4
4
  import { useNavigate } from 'react-router-dom';
5
5
  import { useProcessMessage, useRouteExecution } from '../../hooks';
@@ -11,7 +11,10 @@ import { ListItem, ListItemButton } from './ActiveSwaps.style';
11
11
  export const ActiveSwapItem = ({ routeId, dense }) => {
12
12
  var _a;
13
13
  const navigate = useNavigate();
14
- const { route, status } = useRouteExecution(routeId, true);
14
+ const { route, status } = useRouteExecution({
15
+ routeId,
16
+ executeInBackground: true,
17
+ });
15
18
  // TODO: replace with ES2023 findLast
16
19
  const lastActiveStep = route === null || route === void 0 ? void 0 : route.steps.slice().reverse().find((step) => step.execution);
17
20
  const lastActiveProcess = (_a = lastActiveStep === null || lastActiveStep === void 0 ? void 0 : lastActiveStep.execution) === null || _a === void 0 ? void 0 : _a.process.at(-1);
@@ -27,7 +30,7 @@ export const ActiveSwapItem = ({ routeId, dense }) => {
27
30
  case 'ACTION_REQUIRED':
28
31
  return _jsx(InfoIcon, { color: "info", fontSize: "small" });
29
32
  case 'FAILED':
30
- return _jsx(WarningIcon, { color: "error", fontSize: "small" });
33
+ return _jsx(ErrorIcon, { color: "error", fontSize: "small" });
31
34
  default:
32
35
  return (_jsx(Typography, Object.assign({ fontSize: 14, fontWeight: 500 }, { children: _jsx(StepTimer, { step: lastActiveStep, hideInProgress: true }) })));
33
36
  }
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { WarningAmber as WarningIcon } from '@mui/icons-material';
13
+ import { WarningAmberRounded as WarningIcon } from '@mui/icons-material';
14
14
  import { Box, Collapse, Typography } from '@mui/material';
15
15
  import { useTranslation } from 'react-i18next';
16
16
  import { useGasSufficiency } from '../../hooks';
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ArrowBack as ArrowBackIcon, History as HistoryIcon, SettingsOutlined as SettingsIcon, } from '@mui/icons-material';
2
+ import { ArrowBack as ArrowBackIcon, ReceiptLongRounded as HistoryIcon, SettingsOutlined as SettingsIcon } from '@mui/icons-material';
3
3
  import { Box, IconButton, Tooltip, Typography } from '@mui/material';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Route, Routes, useLocation } from 'react-router-dom';
6
6
  import { useNavigateBack } from '../../hooks';
7
7
  import { useWallet, useWidgetConfig } from '../../providers';
8
- import { backButtonRoutes, navigationRoutes, navigationRoutesValues, } from '../../utils';
8
+ import { backButtonRoutes, navigationRoutes, navigationRoutesValues } from '../../utils';
9
9
  import { HeaderAppBar } from './Header.style';
10
10
  import { useHeaderActionStore } from './useHeaderActionStore';
11
11
  export const NavigationHeader = () => {
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
11
- import { ContentCopy as ContentCopyIcon, ExpandMore as ExpandMoreIcon, PowerSettingsNew as PowerSettingsIcon, WalletOutlined as WalletOutlinedIcon, } from '@mui/icons-material';
11
+ import { ContentCopy as ContentCopyIcon, ExpandMore as ExpandMoreIcon, PowerSettingsNewRounded as PowerSettingsIcon, WalletOutlined as WalletOutlinedIcon } from '@mui/icons-material';
12
12
  import { Avatar, MenuItem } from '@mui/material';
13
13
  import { useState } from 'react';
14
14
  import { useTranslation } from 'react-i18next';
@@ -6,7 +6,7 @@ export const IconButton = styled(MuiIconButton)(({ theme }) => ({
6
6
  borderColor: theme.palette.mode === 'light'
7
7
  ? theme.palette.grey[300]
8
8
  : theme.palette.grey[800],
9
- zIndex: 1200,
9
+ zIndex: 1100,
10
10
  padding: theme.spacing(0.5),
11
11
  '&:hover': {
12
12
  backgroundColor: theme.palette.mode === 'light'
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { Status } from '@lifi/sdk';
3
- export declare function CircularProgress({ status }: {
4
- status: Status;
2
+ import type { Process } from '@lifi/sdk';
3
+ export declare function CircularProgress({ process }: {
4
+ process: Process;
5
5
  }): JSX.Element;
@@ -1,19 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Done as DoneIcon, Info as InfoIcon, Warning as WarningIcon } from '@mui/icons-material';
3
- import { Box } from '@mui/material';
4
- import { CircularProgress as CircularProgressStyled, CircularProgressPending } from './CircularProgress.style';
5
- export function CircularProgress({ status }) {
6
- return (_jsxs(Box, Object.assign({ sx: {
7
- display: 'grid',
8
- position: 'relative',
9
- placeItems: 'center',
10
- } }, { children: [_jsx(CircularProgressStyled, { variant: "determinate", status: status, size: 32, thickness: 3, value: 100 }), status === 'STARTED' || status === 'PENDING' ? (_jsx(CircularProgressPending, { size: 32, thickness: 3 })) : null, status === 'ACTION_REQUIRED' ? (_jsx(InfoIcon, { color: "info", sx: {
2
+ import { Done as DoneIcon, ErrorRounded as ErrorIcon, InfoRounded as InfoIcon, WarningRounded as WarningIcon } from '@mui/icons-material';
3
+ import { darken } from '@mui/material/styles';
4
+ import { CircularIcon, CircularProgressPending } from './CircularProgress.style';
5
+ export function CircularProgress({ process }) {
6
+ return (_jsxs(CircularIcon, Object.assign({ status: process.status, substatus: process.substatus }, { children: [process.status === 'STARTED' || process.status === 'PENDING' ? (_jsx(CircularProgressPending, { size: 32, thickness: 3 })) : null, process.status === 'ACTION_REQUIRED' ? (_jsx(InfoIcon, { color: "info", sx: {
11
7
  position: 'absolute',
12
8
  fontSize: '1rem',
13
- } })) : null, status === 'DONE' ? (_jsx(DoneIcon, { color: "success", sx: {
9
+ } })) : null, process.status === 'DONE' &&
10
+ (process.substatus === 'PARTIAL' || process.substatus === 'REFUNDED') ? (_jsx(WarningIcon, { sx: (theme) => ({
14
11
  position: 'absolute',
15
12
  fontSize: '1rem',
16
- } })) : null, status === 'FAILED' ? (_jsx(WarningIcon, { color: "error", sx: {
13
+ color: darken(theme.palette.warning.main, 0.32),
14
+ }) })) : process.status === 'DONE' ? (_jsx(DoneIcon, { color: "success", sx: {
15
+ position: 'absolute',
16
+ fontSize: '1rem',
17
+ } })) : null, process.status === 'FAILED' ? (_jsx(ErrorIcon, { color: "error", sx: {
17
18
  position: 'absolute',
18
19
  fontSize: '1rem',
19
20
  } })) : null] })));
@@ -1,6 +1,15 @@
1
- import type { Status } from '@lifi/sdk';
2
- import type { Theme } from '@mui/material';
3
- export declare const CircularProgress: import("@emotion/styled").StyledComponent<import("@mui/material").CircularProgressProps & import("@mui/system").MUIStyledCommonProps<Theme> & {
1
+ /// <reference types="react" />
2
+ import type { Status, Substatus } from '@lifi/sdk';
3
+ import { Theme } from '@mui/material';
4
+ export declare const CircularIcon: import("@emotion/styled").StyledComponent<import("@mui/system").SystemProps<Theme> & {
5
+ children?: import("react").ReactNode;
6
+ component?: import("react").ElementType<any> | undefined;
7
+ ref?: import("react").Ref<unknown> | undefined;
8
+ sx?: import("@mui/material").SxProps<Theme> | undefined;
9
+ } & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof import("react").HTMLAttributes<HTMLDivElement>> & {
10
+ ref?: import("react").RefObject<HTMLDivElement> | ((instance: HTMLDivElement | null) => void) | null | undefined;
11
+ }, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "ref" | ("p" | "color" | "border" | "boxShadow" | "fontWeight" | "zIndex" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxSizing" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "letterSpacing" | "lineHeight" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "textTransform" | "top" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "flex" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "overflow" | "padding" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "typography" | "displayPrint") | "component"> & import("@mui/system").MUIStyledCommonProps<Theme> & {
4
12
  status: Status;
13
+ substatus?: Substatus | undefined;
5
14
  }, {}, {}>;
6
15
  export declare const CircularProgressPending: import("@emotion/styled").StyledComponent<import("@mui/material").CircularProgressProps & import("@mui/system").MUIStyledCommonProps<Theme>, {}, {}>;
@@ -1,6 +1,6 @@
1
- import { CircularProgress as MuiCircularProgress } from '@mui/material';
1
+ import { Box, CircularProgress as MuiCircularProgress } from '@mui/material';
2
2
  import { circularProgressClasses } from '@mui/material/CircularProgress';
3
- import { keyframes, styled } from '@mui/material/styles';
3
+ import { alpha, keyframes, styled } from '@mui/material/styles';
4
4
  const circleAnimation = keyframes({
5
5
  '0%': {
6
6
  strokeDashoffset: 129,
@@ -15,22 +15,38 @@ const circleAnimation = keyframes({
15
15
  transform: 'rotate(360deg)',
16
16
  },
17
17
  });
18
- const getStatusColor = (status, theme) => {
18
+ const getStatusColor = (theme, status, substatus) => {
19
19
  switch (status) {
20
20
  case 'ACTION_REQUIRED':
21
- return theme.palette.info.main;
21
+ return alpha(theme.palette.info.main, 0.12);
22
22
  case 'DONE':
23
- return theme.palette.success.main;
23
+ if (substatus === 'PARTIAL' || substatus === 'REFUNDED') {
24
+ return alpha(theme.palette.warning.main, 0.48);
25
+ }
26
+ return alpha(theme.palette.success.main, 0.12);
24
27
  case 'FAILED':
25
- return theme.palette.error.main;
28
+ return alpha(theme.palette.error.main, 0.12);
26
29
  default:
27
30
  return theme.palette.grey[theme.palette.mode === 'light' ? 300 : 800];
28
31
  }
29
32
  };
30
- export const CircularProgress = styled(MuiCircularProgress, {
31
- shouldForwardProp: (prop) => prop !== 'status',
32
- })(({ theme, status }) => ({
33
- color: getStatusColor(status, theme),
33
+ export const CircularIcon = styled(Box, {
34
+ shouldForwardProp: (prop) => !['status', 'substatus'].includes(prop),
35
+ })(({ theme, status, substatus }) => ({
36
+ backgroundColor: ['ACTION_REQUIRED', 'DONE', 'FAILED'].includes(status)
37
+ ? getStatusColor(theme, status, substatus)
38
+ : theme.palette.background.paper,
39
+ borderStyle: 'solid',
40
+ borderColor: getStatusColor(theme, status, substatus),
41
+ borderWidth: !['ACTION_REQUIRED', 'DONE', 'FAILED'].includes(status)
42
+ ? 2
43
+ : 0,
44
+ display: 'grid',
45
+ position: 'relative',
46
+ placeItems: 'center',
47
+ width: 32,
48
+ height: 32,
49
+ borderRadius: '50%',
34
50
  }));
35
51
  export const CircularProgressPending = styled(MuiCircularProgress)(({ theme }) => ({
36
52
  color: theme.palette.mode === 'light'
@@ -38,7 +54,7 @@ export const CircularProgressPending = styled(MuiCircularProgress)(({ theme }) =
38
54
  : theme.palette.primary.light,
39
55
  animationDuration: '3s',
40
56
  position: 'absolute',
41
- left: 0,
57
+ left: '-2px',
42
58
  [`.${circularProgressClasses.circle}`]: {
43
59
  animationDuration: '2s',
44
60
  animationTimingFunction: 'linear',
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import type { Step } from '@lifi/sdk';
3
+ export declare const DestinationWalletAddress: React.FC<{
4
+ step: Step;
5
+ toAddress: string;
6
+ toAddressLink: string;
7
+ }>;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LinkRounded as LinkIcon, WalletOutlined as WalletOutlinedIcon } from '@mui/icons-material';
3
+ import { Box, Link, Typography } from '@mui/material';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { CircularIcon } from './CircularProgress.style';
6
+ import { LinkButton } from './StepProcess.style';
7
+ export const DestinationWalletAddress = ({ step, toAddress, toAddressLink }) => {
8
+ var _a;
9
+ const { t } = useTranslation();
10
+ const isDone = ((_a = step.execution) === null || _a === void 0 ? void 0 : _a.status) === 'DONE';
11
+ return (_jsx(Box, Object.assign({ px: 2, py: 1 }, { children: _jsxs(Box, Object.assign({ sx: {
12
+ display: 'flex',
13
+ alignItems: 'center',
14
+ } }, { children: [_jsx(CircularIcon, Object.assign({ status: isDone ? 'DONE' : 'NOT_STARTED' }, { children: _jsx(WalletOutlinedIcon, { color: isDone ? 'success' : 'inherit', sx: {
15
+ position: 'absolute',
16
+ fontSize: '1rem',
17
+ } }) })), _jsx(Typography, Object.assign({ ml: 2, fontSize: 14, fontWeight: 400 }, { children: isDone
18
+ ? t('swap.sentToAddress', {
19
+ address: toAddress,
20
+ })
21
+ : t('swap.sendToAddress', {
22
+ address: toAddress,
23
+ }) })), _jsx(Box, Object.assign({ ml: 2, sx: {
24
+ display: 'flex',
25
+ flex: 1,
26
+ justifyContent: 'flex-end',
27
+ } }, { children: _jsx(LinkButton, Object.assign({ size: "small", edge: "end", LinkComponent: Link, href: toAddressLink, target: "_blank", rel: "nofollow noreferrer" }, { children: _jsx(LinkIcon, {}) })) }))] })) })));
28
+ };
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import type { Step } from '@lifi/sdk';
3
+ export declare const GasStepProcess: React.FC<{
4
+ step: Step;
5
+ }>;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { EvStationOutlined as EvStationIcon } from '@mui/icons-material';
3
+ import { Box, Typography } from '@mui/material';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { CircularIcon } from './CircularProgress.style';
6
+ export const GasStepProcess = ({ step }) => {
7
+ var _a, _b, _c, _d;
8
+ const { t } = useTranslation();
9
+ const isDone = ((_a = step.execution) === null || _a === void 0 ? void 0 : _a.status) === 'DONE';
10
+ return (_jsx(Box, Object.assign({ px: 2, py: 1 }, { children: _jsxs(Box, Object.assign({ sx: {
11
+ display: 'flex',
12
+ alignItems: 'center',
13
+ } }, { children: [_jsx(CircularIcon, Object.assign({ status: isDone ? 'DONE' : 'NOT_STARTED' }, { children: _jsx(EvStationIcon, { color: isDone ? 'success' : 'inherit', sx: {
14
+ position: 'absolute',
15
+ fontSize: '1rem',
16
+ } }) })), _jsxs(Typography, Object.assign({ ml: 2, fontSize: 14, fontWeight: 400 }, { children: [t('format.currency', {
17
+ value: (_d = (((_b = step.execution) === null || _b === void 0 ? void 0 : _b.gasAmountUSD) ||
18
+ ((_c = step.estimate.gasCosts) === null || _c === void 0 ? void 0 : _c.reduce((amount, gasCost) => amount + parseFloat(gasCost.amountUSD || '0'), 0)))) !== null && _d !== void 0 ? _d : 0,
19
+ }), ' ', isDone ? t('swap.gasFeePaid') : t('swap.gasFeeEstimated')] }))] })) })));
20
+ };
@@ -4,4 +4,5 @@ export declare const Step: React.FC<{
4
4
  step: StepType;
5
5
  fromToken?: TokenAmount;
6
6
  toToken?: TokenAmount;
7
+ toAddress?: string;
7
8
  }>;
@@ -4,19 +4,27 @@ import { useTranslation } from 'react-i18next';
4
4
  import { Card, CardTitle } from '../../components/Card';
5
5
  import { StepActions } from '../../components/StepActions';
6
6
  import { Token } from '../../components/Token';
7
+ import { useChains } from '../../hooks';
8
+ import { shortenWalletAddress } from '../../utils';
9
+ import { DestinationWalletAddress } from './DestinationWalletAddress';
10
+ import { GasStepProcess } from './GasStepProcess';
7
11
  import { StepProcess } from './StepProcess';
8
12
  import { StepTimer } from './StepTimer';
9
- export const Step = ({ step, fromToken, toToken }) => {
10
- var _a, _b;
13
+ export const Step = ({ step, fromToken, toToken, toAddress }) => {
14
+ var _a, _b, _c;
11
15
  const { t } = useTranslation();
16
+ const { getChainById } = useChains();
12
17
  const stepHasError = (_a = step.execution) === null || _a === void 0 ? void 0 : _a.process.some((process) => process.status === 'FAILED');
13
18
  const getCardTitle = () => {
14
19
  switch (step.type) {
15
20
  case 'lifi':
16
- if (step.includedSteps.some((step) => step.type === 'cross')) {
17
- return t('swap.stepSwapAndBridge');
21
+ if (step.includedSteps.every((step) => step.type === 'cross')) {
22
+ return t('swap.stepBridge');
18
23
  }
19
- return t('swap.stepSwap');
24
+ if (step.includedSteps.every((step) => step.type === 'swap')) {
25
+ return t('swap.stepSwap');
26
+ }
27
+ return t('swap.stepSwapAndBridge');
20
28
  case 'swap':
21
29
  return t('swap.stepSwap');
22
30
  case 'cross':
@@ -25,8 +33,12 @@ export const Step = ({ step, fromToken, toToken }) => {
25
33
  return t('swap.stepSwap');
26
34
  }
27
35
  };
36
+ const formattedToAddress = shortenWalletAddress(toAddress);
37
+ const toAddressLink = toAddress
38
+ ? `${(_b = getChainById(step.action.toChainId)) === null || _b === void 0 ? void 0 : _b.metamask.blockExplorerUrls[0]}address/${toAddress}`
39
+ : undefined;
28
40
  return (_jsxs(Card, Object.assign({ variant: stepHasError ? 'error' : 'default' }, { children: [_jsxs(Box, Object.assign({ sx: {
29
41
  display: 'flex',
30
42
  flex: 1,
31
- } }, { children: [_jsx(CardTitle, Object.assign({ flex: 1 }, { children: getCardTitle() })), _jsx(CardTitle, Object.assign({ sx: { fontWeight: 500 } }, { children: _jsx(StepTimer, { step: step }) }))] })), _jsxs(Box, Object.assign({ py: 1 }, { children: [fromToken ? _jsx(Token, { token: fromToken, px: 2, py: 1 }) : null, _jsx(StepActions, { step: step, px: 2, py: 1, dense: true }), (_b = step.execution) === null || _b === void 0 ? void 0 : _b.process.map((process, index) => (_jsx(StepProcess, { step: step, process: process }, index))), toToken ? _jsx(Token, { token: toToken, px: 2, py: 1 }) : null] }))] })));
43
+ } }, { children: [_jsx(CardTitle, Object.assign({ flex: 1 }, { children: getCardTitle() })), _jsx(CardTitle, Object.assign({ sx: { fontWeight: 500 } }, { children: _jsx(StepTimer, { step: step }) }))] })), _jsxs(Box, Object.assign({ py: 1 }, { children: [fromToken ? _jsx(Token, { token: fromToken, px: 2, py: 1 }) : null, _jsx(StepActions, { step: step, px: 2, py: 1, dense: true }), (_c = step.execution) === null || _c === void 0 ? void 0 : _c.process.map((process, index) => (_jsx(StepProcess, { step: step, process: process }, index))), _jsx(GasStepProcess, { step: step }), formattedToAddress && toAddressLink ? (_jsx(DestinationWalletAddress, { step: step, toAddress: formattedToAddress, toAddressLink: toAddressLink })) : null, toToken ? _jsx(Token, { token: toToken, px: 2, py: 1 }) : null] }))] })));
32
44
  };
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { Route } from '@lifi/sdk';
3
+ export declare const getStepList: (route?: Route) => JSX.Element[] | undefined;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { StepDivider } from '../../components/StepDivider';
4
+ import { Step } from './Step';
5
+ export const getStepList = (route) => route === null || route === void 0 ? void 0 : route.steps.map((step, index, steps) => {
6
+ var _a, _b, _c, _d, _e;
7
+ const lastIndex = steps.length - 1;
8
+ const fromToken = index === 0
9
+ ? Object.assign(Object.assign({}, step.action.fromToken), { amount: step.action.fromAmount }) : undefined;
10
+ const toToken = index === lastIndex
11
+ ? Object.assign(Object.assign({}, ((_b = (_a = step.execution) === null || _a === void 0 ? void 0 : _a.toToken) !== null && _b !== void 0 ? _b : (_c = step.action) === null || _c === void 0 ? void 0 : _c.toToken)), { amount: (_e = (_d = step.execution) === null || _d === void 0 ? void 0 : _d.toAmount) !== null && _e !== void 0 ? _e : step.estimate.toAmount }) : undefined;
12
+ const toAddress = index === lastIndex && route.fromAddress !== route.toAddress
13
+ ? route.toAddress
14
+ : undefined;
15
+ return (_jsxs(Fragment, { children: [_jsx(Step, { step: step, fromToken: fromToken, toToken: toToken, toAddress: toAddress }), steps.length > 1 && index !== steps.length - 1 ? (_jsx(StepDivider, {})) : null] }, step.id));
16
+ });
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Link as LinkIcon } from '@mui/icons-material';
2
+ import { LinkRounded as LinkIcon } from '@mui/icons-material';
3
3
  import { Box, Link, Typography } from '@mui/material';
4
4
  import { useProcessMessage } from '../../hooks';
5
5
  import { CircularProgress } from './CircularProgress';
@@ -9,7 +9,7 @@ export const StepProcess = ({ step, process }) => {
9
9
  return (_jsxs(Box, Object.assign({ px: 2, py: 1 }, { children: [_jsxs(Box, Object.assign({ sx: {
10
10
  display: 'flex',
11
11
  alignItems: 'center',
12
- } }, { children: [_jsx(CircularProgress, { status: process.status }), _jsx(Typography, Object.assign({ ml: 2, fontSize: 14, fontWeight: process.error ? 600 : 400 }, { children: title })), process.txLink ? (_jsx(Box, Object.assign({ ml: 2, sx: {
12
+ } }, { children: [_jsx(CircularProgress, { process: process }), _jsx(Typography, Object.assign({ ml: 2, fontSize: 14, fontWeight: process.error ? 600 : 400 }, { children: title })), process.txLink ? (_jsx(Box, Object.assign({ ml: 2, sx: {
13
13
  display: 'flex',
14
14
  flex: 1,
15
15
  justifyContent: 'flex-end',
@@ -1 +1,2 @@
1
1
  export * from './Step';
2
+ export * from './StepList';
@@ -1 +1,2 @@
1
1
  export * from './Step';
2
+ export * from './StepList';
@@ -48,5 +48,5 @@ export const SwapButton = forwardRef(({ onClick, currentRoute, text, disable, en
48
48
  }
49
49
  return t(`button.connectWallet`);
50
50
  };
51
- return (_jsx(LoadingButton, Object.assign({ variant: "contained", color: account.isActive ? 'primary' : 'success', onClick: handleSwapButtonClick, disabled: insufficientFunds || !!(insufficientGas === null || insufficientGas === void 0 ? void 0 : insufficientGas.length) || disable, loading: enableLoading && (loading || isGasSufficiencyLoading), loadingPosition: "center", fullWidth: true, ref: ref }, { children: getButtonText() })));
51
+ return (_jsx(LoadingButton, Object.assign({ variant: "contained", color: "primary", onClick: handleSwapButtonClick, disabled: insufficientFunds || !!(insufficientGas === null || insufficientGas === void 0 ? void 0 : insufficientGas.length) || disable, loading: enableLoading && (loading || isGasSufficiencyLoading), loadingPosition: "center", fullWidth: true, ref: ref }, { children: getButtonText() })));
52
52
  });
@@ -10,5 +10,5 @@ export const SwapRouteNotFoundCard = () => {
10
10
  justifyContent: 'center',
11
11
  flexDirection: 'column',
12
12
  flex: 1,
13
- }, py: 2.375 }, { children: [_jsx(Typography, Object.assign({ fontSize: 48 }, { children: _jsx(RouteIcon, { fontSize: "inherit" }) })), _jsx(Typography, Object.assign({ fontSize: 18, fontWeight: 700 }, { children: t('swap.info.title.routeNotFound') })), _jsx(Typography, Object.assign({ fontSize: 14, color: "text.secondary", textAlign: "center", mt: 2 }, { children: t('swap.info.message.routeNotFound') }))] })));
13
+ }, py: 1.625 }, { children: [_jsx(Typography, Object.assign({ fontSize: 48 }, { children: _jsx(RouteIcon, { fontSize: "inherit" }) })), _jsx(Typography, Object.assign({ fontSize: 18, fontWeight: 700 }, { children: t('swap.info.title.routeNotFound') })), _jsx(Typography, Object.assign({ fontSize: 14, color: "text.secondary", textAlign: "center", mt: 2 }, { children: t('swap.info.message.routeNotFound') }))] })));
14
14
  };
@@ -9,6 +9,12 @@ export const useTokenSelect = (formType, onClick) => {
9
9
  onChange(tokenAddress);
10
10
  onBlur();
11
11
  const selectedChainId = chainId !== null && chainId !== void 0 ? chainId : getValues(SwapFormKeyHelper.getChainKey(formType));
12
+ // Set chain again to trigger URL builder update
13
+ setValue(SwapFormKeyHelper.getChainKey(formType), selectedChainId, {
14
+ shouldDirty: true,
15
+ shouldTouch: true,
16
+ });
17
+ setValue(SwapFormKeyHelper.getAmountKey(formType), '');
12
18
  const oppositeFormType = formType === 'from' ? 'to' : 'from';
13
19
  const [selectedOppositeToken, selectedOppositeChainId] = getValues([
14
20
  SwapFormKeyHelper.getTokenKey(oppositeFormType),
@@ -21,12 +27,6 @@ export const useTokenSelect = (formType, onClick) => {
21
27
  shouldTouch: true,
22
28
  });
23
29
  }
24
- // Set chain again to trigger URL builder update
25
- setValue(SwapFormKeyHelper.getChainKey(formType), selectedChainId, {
26
- shouldDirty: true,
27
- shouldTouch: true,
28
- });
29
- setValue(SwapFormKeyHelper.getAmountKey(formType), '');
30
30
  onClick === null || onClick === void 0 ? void 0 : onClick();
31
31
  }, [formType, getValues, onBlur, onChange, onClick, setValue]);
32
32
  };
package/config/sentry.js CHANGED
@@ -27,7 +27,7 @@ export const initSentry = (enabled) => __awaiter(void 0, void 0, void 0, functio
27
27
  levels: ['error'],
28
28
  }),
29
29
  ],
30
- sampleRate: 1,
30
+ sampleRate: 0.25,
31
31
  tracesSampleRate: 0.2,
32
32
  enabled,
33
33
  environment: process.env.NODE_ENV,
@@ -1,2 +1,2 @@
1
1
  export declare const name = "@lifi/widget";
2
- export declare const version = "1.25.0";
2
+ export declare const version = "1.26.0";
package/config/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget';
2
- export const version = '1.25.0';
2
+ export const version = '1.26.0';
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { useQuery } from '@tanstack/react-query';
11
11
  import { useCallback } from 'react';
12
12
  import { useFormContext } from 'react-hook-form';
13
- import { isItemAllowed, SwapFormKey, useLiFi, useWidgetConfig, } from '../providers';
13
+ import { isItemAllowed, SwapFormKey, useLiFi, useWidgetConfig } from '../providers';
14
14
  import { useChainOrderStore } from '../stores';
15
15
  export const useChains = () => {
16
16
  const { disabledChains, chains } = useWidgetConfig();
@@ -33,7 +33,10 @@ export const useChains = () => {
33
33
  setValue(SwapFormKey.ToChain, chainOrder[0]);
34
34
  }
35
35
  return { availableChains, filteredChains };
36
- }));
36
+ }), {
37
+ refetchInterval: 180000,
38
+ staleTime: 180000,
39
+ });
37
40
  const getChainById = useCallback((chainId) => {
38
41
  const chain = data === null || data === void 0 ? void 0 : data.availableChains.find((chain) => chain.id === chainId);
39
42
  // if (!chain) {
@@ -10,7 +10,7 @@ export const useProcessMessage = (step, process) => {
10
10
  }
11
11
  return getProcessMessage(t, getChainById, step, process);
12
12
  };
13
- const processMessages = {
13
+ const processStatusMessages = {
14
14
  TOKEN_ALLOWANCE: {
15
15
  STARTED: (t) => t(`swap.process.tokenAllowance.started`),
16
16
  PENDING: (t) => t(`swap.process.tokenAllowance.pending`),
@@ -38,8 +38,34 @@ const processMessages = {
38
38
  },
39
39
  TRANSACTION: {},
40
40
  };
41
+ const processSubstatusMessages = {
42
+ PENDING: {
43
+ // BRIDGE_NOT_AVAILABLE: 'Bridge communication is temporarily unavailable.',
44
+ // CHAIN_NOT_AVAILABLE: 'RPC communication is temporarily unavailable.',
45
+ // REFUND_IN_PROGRESS:
46
+ // "The refund has been requested and it's being processed",
47
+ // WAIT_DESTINATION_TRANSACTION:
48
+ // 'The bridge off-chain logic is being executed. Wait for the transaction to appear on the destination chain.',
49
+ // WAIT_SOURCE_CONFIRMATIONS:
50
+ // 'The bridge deposit has been received. The bridge is waiting for more confirmations to start the off-chain logic.',
51
+ },
52
+ DONE: {
53
+ // COMPLETED: 'The transfer is complete.',
54
+ PARTIAL: (t) => t(`swap.process.receivingChain.partial`),
55
+ REFUNDED: (t) => t(`swap.process.receivingChain.partial`),
56
+ },
57
+ FAILED: {
58
+ // TODO: should be moved to failed status
59
+ // NOT_PROCESSABLE_REFUND_NEEDED:
60
+ // 'The transfer cannot be completed successfully. A refund operation is required.',
61
+ // UNKNOWN_ERROR:
62
+ // 'An unexpected error occurred. Please seek assistance in the LI.FI discord server.',
63
+ },
64
+ INVALID: {},
65
+ NOT_FOUND: {},
66
+ };
41
67
  export function getProcessMessage(t, getChainById, step, process) {
42
- var _a, _b, _c, _d;
68
+ var _a, _b, _c, _d, _e, _f, _g;
43
69
  if (process.error && process.status === 'FAILED') {
44
70
  const getTransactionNotSentMessage = () => {
45
71
  var _a, _b;
@@ -52,10 +78,18 @@ export function getProcessMessage(t, getChainById, step, process) {
52
78
  let title = '';
53
79
  let message = '';
54
80
  switch (process.error.code) {
81
+ case LifiErrorCode.BalanceError:
82
+ title = t(`swap.error.title.balanceIsTooLow`);
83
+ message = getTransactionNotSentMessage();
84
+ break;
55
85
  case LifiErrorCode.ChainSwitchError:
56
86
  title = t(`swap.error.title.chainSwitch`);
57
87
  message = getTransactionNotSentMessage();
58
88
  break;
89
+ case LifiErrorCode.GasLimitError:
90
+ title = t(`swap.error.title.gasLimitIsTooLow`);
91
+ message = getTransactionNotSentMessage();
92
+ break;
59
93
  case LifiErrorCode.TransactionFailed:
60
94
  title = t(`swap.error.title.transactionFailed`);
61
95
  message = t(`swap.error.message.transactionFailed`);
@@ -68,9 +102,13 @@ export function getProcessMessage(t, getChainById, step, process) {
68
102
  title = t(`swap.error.title.transactionUnprepared`);
69
103
  message = getTransactionNotSentMessage();
70
104
  break;
105
+ case LifiErrorCode.TransactionCanceled:
106
+ title = t(`swap.error.title.transactionCanceled`);
107
+ message = getTransactionNotSentMessage();
108
+ break;
71
109
  case LifiErrorCode.SlippageError:
72
- title = t(`swap.error.title.slippageTooLarge`);
73
- message = t(`swap.error.message.slippageTooLarge`);
110
+ title = t(`swap.error.title.slippageNotMet`);
111
+ message = t(`swap.error.message.slippageThreshold`);
74
112
  break;
75
113
  case LifiErrorCode.TransactionRejected:
76
114
  title = t(`swap.error.title.transactionRejected`);
@@ -80,15 +118,19 @@ export function getProcessMessage(t, getChainById, step, process) {
80
118
  chainName: (_b = (_a = getChainById(step.action.fromChainId)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '',
81
119
  });
82
120
  break;
121
+ case LifiErrorCode.ProviderUnavailable:
83
122
  default:
84
123
  title = t(`swap.error.title.unknown`);
85
124
  if (process.txLink) {
86
125
  message = t(`swap.error.message.transactionFailed`);
87
126
  }
127
+ else {
128
+ message = t(`swap.error.message.unknown`);
129
+ }
88
130
  break;
89
131
  }
90
132
  return { title, message };
91
133
  }
92
- const title = (_d = (_c = processMessages[process.type]) === null || _c === void 0 ? void 0 : _c[process.status]) === null || _d === void 0 ? void 0 : _d.call(_c, t);
134
+ const title = (_e = (_d = (_c = processSubstatusMessages[process.status]) === null || _c === void 0 ? void 0 : _c[process.substatus]) === null || _d === void 0 ? void 0 : _d.call(_c, t)) !== null && _e !== void 0 ? _e : (_g = (_f = processStatusMessages[process.type]) === null || _f === void 0 ? void 0 : _f[process.status]) === null || _g === void 0 ? void 0 : _g.call(_f, t);
93
135
  return { title };
94
136
  }
@@ -1,8 +1,14 @@
1
- import type { Route } from '@lifi/sdk';
2
- export declare const useRouteExecution: (routeId: string, executeInBackground?: boolean) => {
1
+ import type { ExchangeRateUpdateParams, Route } from '@lifi/sdk';
2
+ interface RouteExecutionProps {
3
+ routeId: string;
4
+ executeInBackground?: boolean;
5
+ onAcceptExchangeRateUpdate?(resolver: (value: boolean) => void, data: ExchangeRateUpdateParams): void;
6
+ }
7
+ export declare const useRouteExecution: ({ routeId, executeInBackground, onAcceptExchangeRateUpdate, }: RouteExecutionProps) => {
3
8
  executeRoute: () => void;
4
9
  restartRoute: () => void;
5
10
  deleteRoute: () => void;
6
11
  route: Route | undefined;
7
12
  status: import("../stores").RouteExecutionStatus | undefined;
8
13
  };
14
+ export {};