@lifi/widget 1.8.0 → 1.10.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.
- package/App.js +1 -1
- package/AppDrawer.style.d.ts +1 -1
- package/README.md +82 -6
- package/components/Header/Header.js +1 -1
- package/components/ReverseTokensButton/ReverseTokensButton.style.d.ts +1 -1
- package/components/SwapButton/SwapButton.d.ts +2 -1
- package/components/SwapButton/SwapButton.js +6 -15
- package/components/SwapButton/SwapButton.style.d.ts +1 -1
- package/components/SwapButton/types.d.ts +5 -0
- package/components/SwapButton/types.js +1 -0
- package/components/SwapInput/SwapInput.style.d.ts +1 -1
- package/components/SwapInput/SwapInputAdornment.style.d.ts +1 -1
- package/components/SwapRouteCard/SwapRouteCardSkeleton.d.ts +4 -0
- package/components/SwapRouteCard/SwapRouteCardSkeleton.js +32 -0
- package/components/SwapRouteCard/SwapRouteNotFoundCard.d.ts +4 -0
- package/components/SwapRouteCard/SwapRouteNotFoundCard.js +27 -0
- package/components/SwapRouteCard/index.d.ts +2 -0
- package/components/SwapRouteCard/index.js +2 -0
- package/components/SwapRouteCard/types.d.ts +5 -0
- package/components/SwapRoutes/SwapRoutes.js +7 -9
- package/config/lifi.d.ts +3 -0
- package/config/lifi.js +11 -0
- package/config/version.d.ts +1 -1
- package/config/version.js +1 -1
- package/hooks/useChains.js +1 -1
- package/hooks/useHasSufficientBalance.js +14 -6
- package/hooks/useRouteExecution.js +1 -1
- package/hooks/useSwapRoutes.d.ts +1 -0
- package/hooks/useSwapRoutes.js +8 -7
- package/hooks/useTokenBalance.js +1 -1
- package/hooks/useTokenBalances.js +1 -1
- package/hooks/useTokens.js +1 -1
- package/hooks/useTools.js +1 -1
- package/i18n/en/translation.json +11 -3
- package/i18n/index.d.ts +8 -0
- package/package.json +4 -4
- package/pages/MainPage/MainPage.js +2 -2
- package/pages/MainPage/MainPage.style.d.ts +1 -1
- package/pages/MainPage/MainPage.style.js +1 -1
- package/pages/MainPage/MainSwapButton.d.ts +2 -0
- package/pages/MainPage/MainSwapButton.js +31 -0
- package/pages/SettingsPage/ColorSchemeButtonGroup.style.d.ts +1 -1
- package/pages/SwapPage/ExecutionItem.style.d.ts +1 -1
- package/pages/SwapPage/SwapPage.js +22 -5
- package/pages/SwapPage/SwapPage.style.d.ts +1 -1
- package/pages/SwapRoutesPage/SwapRoutesPage.js +12 -13
- package/providers/WidgetProvider/WidgetProvider.js +10 -2
- package/stores/route/useRouteStore.js +1 -1
- package/types/widget.d.ts +1 -0
- package/utils/format.js +3 -3
- package/lifi.d.ts +0 -2
- package/lifi.js +0 -7
package/App.js
CHANGED
|
@@ -23,5 +23,5 @@ export const AppDefault = () => {
|
|
|
23
23
|
attemptEagerConnect();
|
|
24
24
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
25
|
}, []);
|
|
26
|
-
return (_jsxs(AppContainer, { children: [_jsx(Header, {}), _jsxs(Routes, { children: [_jsx(Route, { path: routes.home, element: _jsx(MainPage, {}) }), _jsx(Route, { path: routes.selectWallet, element: _jsx(SelectWalletPage, {}) }), _jsx(Route, { path: routes.settings, element: _jsx(SettingsPage, {}) }), _jsx(Route, { path: routes.fromToken, element: _jsx(SelectTokenPage, { formType: "from" }) }), _jsx(Route, { path: routes.toToken, element: _jsx(SelectTokenPage, { formType: "to" }) }), _jsx(Route, { path: routes.swapRoutes, element: _jsx(SwapRoutesPage, {}) }), _jsx(Route, { path: `${routes.swapRoutes}/${routes.swap}`, element: _jsx(SwapPage, {}) }), _jsx(Route, { path: routes.swap, element: _jsx(SwapPage, {}) }), _jsx(Route, { path: "*", element: _jsx(NotFound, {}) })] }), _jsx(Initializer, {})] }));
|
|
26
|
+
return (_jsxs(AppContainer, { children: [_jsx(Header, {}), _jsxs(Routes, { children: [_jsx(Route, { path: routes.home, element: _jsx(MainPage, {}) }), _jsx(Route, { path: routes.selectWallet, element: _jsx(SelectWalletPage, {}) }), _jsx(Route, { path: `${routes.swapRoutes}/${routes.swap}/${routes.selectWallet}`, element: _jsx(SelectWalletPage, {}) }), _jsx(Route, { path: routes.settings, element: _jsx(SettingsPage, {}) }), _jsx(Route, { path: routes.fromToken, element: _jsx(SelectTokenPage, { formType: "from" }) }), _jsx(Route, { path: routes.toToken, element: _jsx(SelectTokenPage, { formType: "to" }) }), _jsx(Route, { path: routes.swapRoutes, element: _jsx(SwapRoutesPage, {}) }), _jsx(Route, { path: `${routes.swapRoutes}/${routes.swap}`, element: _jsx(SwapPage, {}) }), _jsx(Route, { path: routes.swap, element: _jsx(SwapPage, {}) }), _jsx(Route, { path: "*", element: _jsx(NotFound, {}) })] }), _jsx(Initializer, {})] }));
|
|
27
27
|
};
|
package/AppDrawer.style.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const DrawerButton: import("@emotion/styled").StyledComponent<{
|
|
3
3
|
children?: import("react").ReactNode;
|
|
4
4
|
classes?: Partial<import("@mui/material").ButtonClasses> | undefined;
|
|
5
|
-
color?: "inherit" | "success" | "
|
|
5
|
+
color?: "inherit" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
6
6
|
disabled?: boolean | undefined;
|
|
7
7
|
disableElevation?: boolean | undefined;
|
|
8
8
|
disableFocusRipple?: boolean | undefined;
|
package/README.md
CHANGED
|
@@ -1,19 +1,95 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](/LICENSE.md)
|
|
4
|
+
[](https://www.npmjs.com/package/@lifi/widget)
|
|
5
|
+
[](https://www.npmjs.com/package/@lifi/widget)
|
|
6
|
+
[](https://isitmaintained.com/project/lifinance/widget)
|
|
7
|
+
[](https://twitter.com/lifiprotocol)
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<h1 align="center">LI.FI Widget</h1>
|
|
12
|
+
|
|
13
|
+
This repository contains LI.FI Widget and supporting libraries.
|
|
14
|
+
|
|
15
|
+
- [_LI.FI Widget_](https://li.fi/widget/) for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.
|
|
16
|
+
|
|
17
|
+
- [_LI.FI Wallet Management_](https://www.npmjs.com/package/@lifi/wallet-management) is our library of hooks that can help you gain complete control over your app's wallet management.
|
|
4
18
|
|
|
5
19
|
## Installation
|
|
6
20
|
|
|
7
|
-
|
|
21
|
+
### LI.FI Widget
|
|
22
|
+
|
|
23
|
+
LI.FI Widget is available as an [npm package](https://www.npmjs.com/package/@lifi/widget).
|
|
24
|
+
|
|
25
|
+
**npm:**
|
|
8
26
|
|
|
9
27
|
```sh
|
|
10
|
-
// with npm
|
|
11
28
|
npm install @lifi/widget
|
|
29
|
+
```
|
|
12
30
|
|
|
13
|
-
|
|
31
|
+
**yarn:**
|
|
32
|
+
|
|
33
|
+
```sh
|
|
14
34
|
yarn add @lifi/widget
|
|
15
35
|
```
|
|
16
36
|
|
|
37
|
+
### LI.FI Wallet Management
|
|
38
|
+
|
|
39
|
+
LI.FI Wallet Management is available as an [npm package](https://www.npmjs.com/package/@lifi/wallet-management).
|
|
40
|
+
|
|
41
|
+
**npm:**
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm install @lifi/wallet-management
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**yarn:**
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
yarn add @lifi/wallet-management
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Getting started with LI.FI Widget
|
|
54
|
+
|
|
55
|
+
Here is an example of a basic app using LI.FI Widget:
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
import { LiFiWidget, WidgetConfig } from '@lifi/widget';
|
|
59
|
+
import { useMemo } from 'react';
|
|
60
|
+
|
|
61
|
+
export const WidgetPage = () => {
|
|
62
|
+
const widgetConfig: WidgetConfig = useMemo(() => {
|
|
63
|
+
return {
|
|
64
|
+
containerStyle: {
|
|
65
|
+
border: `1px solid ${
|
|
66
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
67
|
+
? 'rgb(66, 66, 66)'
|
|
68
|
+
: 'rgb(234, 234, 234)'
|
|
69
|
+
}`,
|
|
70
|
+
borderRadius: '16px',
|
|
71
|
+
display: 'flex',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}, []);
|
|
75
|
+
|
|
76
|
+
return <LiFiWidget config={widgetConfig} />;
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
Visit our [playground](https://testing.li.finance) to see how you can customize your [LI.FI Widget](https://www.npmjs.com/package/@lifi/widget) experience.
|
|
83
|
+
|
|
17
84
|
## Documentation
|
|
18
85
|
|
|
19
|
-
[
|
|
86
|
+
[LI.FI Documentation](https://docs.li.fi)
|
|
87
|
+
|
|
88
|
+
## Changelog
|
|
89
|
+
|
|
90
|
+
The [changelog](/CHANGELOG.md) is regularly updated to reflect what's changed in each new release.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
This project is licensed under the terms of the
|
|
95
|
+
[Apache-2.0](/LICENSE.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useWidgetConfig } from '@lifi/widget/providers/WidgetProvider';
|
|
3
2
|
import { useLocation } from 'react-router-dom';
|
|
3
|
+
import { useWidgetConfig } from '../../providers/WidgetProvider';
|
|
4
4
|
import { ElementId } from '../../utils/elements';
|
|
5
5
|
import { routes } from '../../utils/routes';
|
|
6
6
|
import { Container } from './Header.style';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const IconButton: import("@emotion/styled").StyledComponent<{
|
|
3
3
|
children?: import("react").ReactNode;
|
|
4
4
|
classes?: Partial<import("@mui/material").IconButtonClasses> | undefined;
|
|
5
|
-
color?: "inherit" | "default" | "success" | "
|
|
5
|
+
color?: "inherit" | "default" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
6
6
|
disabled?: boolean | undefined;
|
|
7
7
|
disableFocusRipple?: boolean | undefined;
|
|
8
8
|
edge?: false | "end" | "start" | undefined;
|
|
@@ -12,23 +12,19 @@ import { ChainId } from '@lifi/sdk';
|
|
|
12
12
|
import { useWatch } from 'react-hook-form';
|
|
13
13
|
import { useTranslation } from 'react-i18next';
|
|
14
14
|
import { useNavigate } from 'react-router-dom';
|
|
15
|
-
import { useChains, useHasSufficientBalance
|
|
15
|
+
import { useChains, useHasSufficientBalance } from '../../hooks';
|
|
16
16
|
import { SwapFormKeyHelper } from '../../providers/SwapFormProvider';
|
|
17
17
|
import { useWallet } from '../../providers/WalletProvider';
|
|
18
18
|
import { useWidgetConfig } from '../../providers/WidgetProvider';
|
|
19
|
-
import { useCurrentRoute, useSetExecutableRoute } from '../../stores';
|
|
20
19
|
import { routes } from '../../utils/routes';
|
|
21
20
|
import { Button } from './SwapButton.style';
|
|
22
|
-
export const SwapButton = () => {
|
|
21
|
+
export const SwapButton = ({ onClick, text, loading, }) => {
|
|
23
22
|
var _a;
|
|
24
23
|
const navigate = useNavigate();
|
|
25
24
|
const { t } = useTranslation();
|
|
26
25
|
const { getChainById } = useChains();
|
|
27
26
|
const config = useWidgetConfig();
|
|
28
27
|
const { account, switchChain, connect: walletConnect } = useWallet();
|
|
29
|
-
const [currentRoute] = useCurrentRoute();
|
|
30
|
-
const setExecutableRoute = useSetExecutableRoute();
|
|
31
|
-
const { routes: swapRoutes, isLoading, isFetching } = useSwapRoutes();
|
|
32
28
|
const { hasGasOnStartChain, hasGasOnCrossChain, hasSufficientBalance } = useHasSufficientBalance();
|
|
33
29
|
const [chainId] = useWatch({
|
|
34
30
|
name: [SwapFormKeyHelper.getChainKey('from')],
|
|
@@ -47,12 +43,8 @@ export const SwapButton = () => {
|
|
|
47
43
|
yield switchChain(chainId);
|
|
48
44
|
// check that the current route exists in the up to date route list
|
|
49
45
|
}
|
|
50
|
-
else
|
|
51
|
-
|
|
52
|
-
setExecutableRoute(currentRoute);
|
|
53
|
-
navigate(routes.swap, {
|
|
54
|
-
state: { routeId: currentRoute.id },
|
|
55
|
-
});
|
|
46
|
+
else {
|
|
47
|
+
onClick === null || onClick === void 0 ? void 0 : onClick();
|
|
56
48
|
}
|
|
57
49
|
});
|
|
58
50
|
const getButtonText = () => {
|
|
@@ -60,7 +52,7 @@ export const SwapButton = () => {
|
|
|
60
52
|
if (!isCurrentChainMatch) {
|
|
61
53
|
return t(`button.switchChain`);
|
|
62
54
|
}
|
|
63
|
-
return t(`button.swap`);
|
|
55
|
+
return text || t(`button.swap`);
|
|
64
56
|
}
|
|
65
57
|
return t(`button.connectWallet`);
|
|
66
58
|
};
|
|
@@ -69,7 +61,6 @@ export const SwapButton = () => {
|
|
|
69
61
|
disabled: (!hasSufficientBalance ||
|
|
70
62
|
!hasGasOnStartChain ||
|
|
71
63
|
!hasGasOnCrossChain ||
|
|
72
|
-
|
|
73
|
-
isFetching) &&
|
|
64
|
+
loading) &&
|
|
74
65
|
isCurrentChainMatch }, { children: getButtonText() })));
|
|
75
66
|
};
|
|
@@ -17,7 +17,7 @@ export declare const Button: import("@emotion/styled").StyledComponent<{
|
|
|
17
17
|
} & Omit<{
|
|
18
18
|
children?: import("react").ReactNode;
|
|
19
19
|
classes?: Partial<import("@mui/material").ButtonClasses> | undefined;
|
|
20
|
-
color?: "inherit" | "success" | "
|
|
20
|
+
color?: "inherit" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
21
21
|
disabled?: boolean | undefined;
|
|
22
22
|
disableElevation?: boolean | undefined;
|
|
23
23
|
disableFocusRipple?: boolean | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,7 +4,7 @@ export declare const minInputFontSize = 14;
|
|
|
4
4
|
export declare const FormControl: import("@emotion/styled").StyledComponent<{
|
|
5
5
|
children?: import("react").ReactNode;
|
|
6
6
|
classes?: Partial<import("@mui/material").FormControlClasses> | undefined;
|
|
7
|
-
color?: "success" | "
|
|
7
|
+
color?: "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
8
8
|
disabled?: boolean | undefined;
|
|
9
9
|
error?: boolean | undefined;
|
|
10
10
|
fullWidth?: boolean | undefined;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const Button: import("@emotion/styled").StyledComponent<{
|
|
3
3
|
children?: import("react").ReactNode;
|
|
4
4
|
classes?: Partial<import("@mui/material").ButtonClasses> | undefined;
|
|
5
|
-
color?: "inherit" | "success" | "
|
|
5
|
+
color?: "inherit" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
6
6
|
disabled?: boolean | undefined;
|
|
7
7
|
disableElevation?: boolean | undefined;
|
|
8
8
|
disableFocusRipple?: boolean | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Box, Skeleton } from '@mui/material';
|
|
14
|
+
import { Card } from './SwapRouteCard.style';
|
|
15
|
+
export const SwapRouteCardSkeleton = (_a) => {
|
|
16
|
+
var { active, dense } = _a, other = __rest(_a, ["active", "dense"]);
|
|
17
|
+
return (_jsxs(Card, Object.assign({ dense: dense }, other, { children: [_jsxs(Box, Object.assign({ sx: {
|
|
18
|
+
display: 'flex',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
justifyContent: 'space-between',
|
|
21
|
+
} }, { children: [_jsx(Skeleton, { variant: "rectangular", width: 120, height: 24, sx: { borderRadius: 0.5 } }), active ? _jsx(Skeleton, { variant: "circular", width: 24, height: 24 }) : null] })), _jsxs(Box, Object.assign({ my: 2 }, { children: [_jsxs(Box, Object.assign({ sx: {
|
|
22
|
+
display: 'flex',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
} }, { children: [_jsx(Box, Object.assign({ mr: 2 }, { children: _jsx(Skeleton, { variant: "circular", width: 32, height: 32 }) })), _jsx(Skeleton, { variant: "text", width: 96, height: 32 })] })), _jsx(Box, Object.assign({ ml: 6 }, { children: _jsx(Skeleton, { variant: "text", width: 56, height: 22 }) }))] })), _jsxs(Box, Object.assign({ sx: {
|
|
25
|
+
display: 'flex',
|
|
26
|
+
justifyContent: 'space-between',
|
|
27
|
+
} }, { children: [_jsxs(Box, { children: [_jsx(Skeleton, { variant: "text", width: 56, height: 22 }), _jsx(Skeleton, { variant: "text", width: 52, height: 15 })] }), _jsxs(Box, Object.assign({ sx: {
|
|
28
|
+
display: 'flex',
|
|
29
|
+
alignItems: 'flex-end',
|
|
30
|
+
flexDirection: 'column',
|
|
31
|
+
} }, { children: [_jsx(Skeleton, { variant: "text", width: 40, height: 22 }), _jsx(Skeleton, { variant: "text", width: 48, height: 15 })] }))] }))] })));
|
|
32
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { Route as RouteIcon } from '@mui/icons-material';
|
|
14
|
+
import { Box, Typography } from '@mui/material';
|
|
15
|
+
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { Card } from './SwapRouteCard.style';
|
|
17
|
+
export const SwapRouteNotFoundCard = (_a) => {
|
|
18
|
+
var { active, dense } = _a, other = __rest(_a, ["active", "dense"]);
|
|
19
|
+
const { t } = useTranslation();
|
|
20
|
+
return (_jsx(Card, Object.assign({ active: active, dense: dense }, other, { children: _jsxs(Box, Object.assign({ sx: {
|
|
21
|
+
display: 'flex',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
justifyContent: 'center',
|
|
24
|
+
flexDirection: 'column',
|
|
25
|
+
flex: 1,
|
|
26
|
+
}, py: 1.375 }, { children: [_jsx(RouteIcon, { fontSize: "large" }), _jsx(Typography, Object.assign({ fontSize: 16, fontWeight: "500", mt: 2 }, { children: t('swap.info.title.routeNotFound') })), _jsx(Typography, Object.assign({ fontSize: 14, color: "text.secondary", textAlign: "center", mt: 1 }, { children: t('swap.info.message.routeNotFound') }))] })) })));
|
|
27
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable react/no-array-index-key */
|
|
3
3
|
import { KeyboardArrowRight as KeyboardArrowRightIcon } from '@mui/icons-material';
|
|
4
|
-
import { Box, IconButton
|
|
4
|
+
import { Box, IconButton } from '@mui/material';
|
|
5
5
|
import { useCallback } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { useNavigate } from 'react-router-dom';
|
|
@@ -9,26 +9,24 @@ import { useSwapRoutes } from '../../hooks';
|
|
|
9
9
|
import { useCurrentRoute } from '../../stores';
|
|
10
10
|
import { routes } from '../../utils/routes';
|
|
11
11
|
import { CardContainer, CardTitle } from '../Card';
|
|
12
|
-
import { SwapRouteCard } from '../SwapRouteCard';
|
|
12
|
+
import { SwapRouteCard, SwapRouteCardSkeleton, SwapRouteNotFoundCard, } from '../SwapRouteCard';
|
|
13
13
|
import { Stack } from './SwapRoutes.style';
|
|
14
14
|
import { SwapRoutesUpdateProgress } from './SwapRoutesUpdateProgress';
|
|
15
15
|
export const SwapRoutes = (props) => {
|
|
16
16
|
const { t } = useTranslation();
|
|
17
17
|
const navigate = useNavigate();
|
|
18
18
|
const [currentRoute] = useCurrentRoute();
|
|
19
|
-
const { routes: swapRoutes, isLoading, isFetching } = useSwapRoutes();
|
|
19
|
+
const { routes: swapRoutes, isLoading, isFetching, isFetched, } = useSwapRoutes();
|
|
20
20
|
const handleCardClick = useCallback(() => {
|
|
21
21
|
navigate(routes.swapRoutes);
|
|
22
22
|
}, [navigate]);
|
|
23
|
-
if (!(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && !isLoading && !isFetching) {
|
|
23
|
+
if (!(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && !isLoading && !isFetching && !isFetched) {
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const routeNotFound = !(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && isFetched;
|
|
27
|
+
return (_jsxs(CardContainer, Object.assign({}, props, { children: [_jsx(CardTitle, { children: t('swap.routes') }), !routeNotFound ? (_jsx(SwapRoutesUpdateProgress, { sx: {
|
|
27
28
|
position: 'absolute',
|
|
28
29
|
top: 8,
|
|
29
30
|
right: 8,
|
|
30
|
-
} }), _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center' } }, { children: [_jsx(Stack, Object.assign({ direction: "row", py: 2, pl: 2, pr: 1 }, { children: isLoading || isFetching || !currentRoute ? (_jsx(
|
|
31
|
-
borderRadius: theme.shape.borderRadiusSecondary / theme.shape.borderRadius,
|
|
32
|
-
minWidth: '100%',
|
|
33
|
-
}) })) : (_jsx(SwapRouteCard, { minWidth: "100%", route: currentRoute, active: true, dense: true })) })), _jsx(Box, Object.assign({ py: 1, pr: 1 }, { children: _jsx(IconButton, Object.assign({ onClick: handleCardClick, size: "medium", "aria-label": "swap-routes" }, { children: _jsx(KeyboardArrowRightIcon, {}) })) }))] }))] })));
|
|
31
|
+
} })) : null, _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center' } }, { children: [_jsx(Stack, Object.assign({ direction: "row", py: 2, pl: 2, pr: routeNotFound ? 2 : 1 }, { children: routeNotFound ? (_jsx(SwapRouteNotFoundCard, { minWidth: "100%", dense: true })) : isLoading || isFetching || !currentRoute ? (_jsx(SwapRouteCardSkeleton, { minWidth: "100%", active: true, dense: true })) : (_jsx(SwapRouteCard, { minWidth: "100%", route: currentRoute, active: true, dense: true })) })), !routeNotFound ? (_jsx(Box, Object.assign({ py: 1, pr: 1 }, { children: _jsx(IconButton, Object.assign({ onClick: handleCardClick, size: "medium", "aria-label": "swap-routes" }, { children: _jsx(KeyboardArrowRightIcon, {}) })) }))) : null] }))] })));
|
|
34
32
|
};
|
package/config/lifi.d.ts
ADDED
package/config/lifi.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import LIFI from '@lifi/sdk';
|
|
2
|
+
const defaultConfig = {
|
|
3
|
+
// apiUrl: env.LIFI_API_URL,
|
|
4
|
+
// defaultRouteOptions: {
|
|
5
|
+
// integrator: 'li.fi',
|
|
6
|
+
// },
|
|
7
|
+
};
|
|
8
|
+
export const LiFi = new LIFI(defaultConfig);
|
|
9
|
+
export const updateLiFiConfig = (configUpdate) => {
|
|
10
|
+
LiFi.setConfig(Object.assign(Object.assign({}, defaultConfig), configUpdate));
|
|
11
|
+
};
|
package/config/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const name = "@lifi/widget";
|
|
2
|
-
export declare const version = "1.
|
|
2
|
+
export declare const version = "1.10.0";
|
package/config/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget';
|
|
2
|
-
export const version = '1.
|
|
2
|
+
export const version = '1.10.0';
|
package/hooks/useChains.js
CHANGED
|
@@ -20,7 +20,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
20
20
|
};
|
|
21
21
|
import { useCallback } from 'react';
|
|
22
22
|
import { useQuery } from 'react-query';
|
|
23
|
-
import { LiFi } from '../lifi';
|
|
23
|
+
import { LiFi } from '../config/lifi';
|
|
24
24
|
import { useWidgetConfig } from '../providers/WidgetProvider';
|
|
25
25
|
export const useChains = () => {
|
|
26
26
|
const { disabledChains } = useWidgetConfig();
|
|
@@ -4,10 +4,12 @@ import { useMemo } from 'react';
|
|
|
4
4
|
import { useWatch } from 'react-hook-form';
|
|
5
5
|
import { useDebouncedWatch } from '.';
|
|
6
6
|
import { SwapFormKey, SwapFormKeyHelper } from '../providers/SwapFormProvider';
|
|
7
|
+
import { useWallet } from '../providers/WalletProvider';
|
|
7
8
|
import { useCurrentRoute } from '../stores';
|
|
8
9
|
import { useTokenBalances } from './useTokenBalances';
|
|
9
10
|
export const useHasSufficientBalance = () => {
|
|
10
11
|
var _a;
|
|
12
|
+
const { account } = useWallet();
|
|
11
13
|
const [route] = useCurrentRoute();
|
|
12
14
|
const [fromChainId, toChainId, fromToken] = useWatch({
|
|
13
15
|
name: [
|
|
@@ -23,7 +25,7 @@ export const useHasSufficientBalance = () => {
|
|
|
23
25
|
const hasGasOnStartChain = useMemo(() => {
|
|
24
26
|
var _a, _b, _c, _d, _e;
|
|
25
27
|
const gasToken = (_a = route === null || route === void 0 ? void 0 : route.steps[0].estimate.gasCosts) === null || _a === void 0 ? void 0 : _a[0].token;
|
|
26
|
-
if (!gasToken) {
|
|
28
|
+
if (!account.isActive || !gasToken) {
|
|
27
29
|
return true;
|
|
28
30
|
}
|
|
29
31
|
const gasTokenBalance = Big((_c = (_b = fromChainTokenBalances === null || fromChainTokenBalances === void 0 ? void 0 : fromChainTokenBalances.find((t) => t.address === gasToken.address)) === null || _b === void 0 ? void 0 : _b.amount) !== null && _c !== void 0 ? _c : 0);
|
|
@@ -36,26 +38,32 @@ export const useHasSufficientBalance = () => {
|
|
|
36
38
|
requiredAmount = requiredAmount.plus(tokenBalance);
|
|
37
39
|
}
|
|
38
40
|
return gasTokenBalance.gt(0) && gasTokenBalance.gte(requiredAmount);
|
|
39
|
-
}, [
|
|
41
|
+
}, [
|
|
42
|
+
account.isActive,
|
|
43
|
+
fromChainTokenBalances,
|
|
44
|
+
route === null || route === void 0 ? void 0 : route.fromChainId,
|
|
45
|
+
route === null || route === void 0 ? void 0 : route.fromToken.address,
|
|
46
|
+
route === null || route === void 0 ? void 0 : route.steps,
|
|
47
|
+
]);
|
|
40
48
|
const hasGasOnCrossChain = useMemo(() => {
|
|
41
49
|
var _a, _b, _c, _d, _e, _f;
|
|
42
50
|
const gasToken = (_a = lastStep === null || lastStep === void 0 ? void 0 : lastStep.estimate.gasCosts) === null || _a === void 0 ? void 0 : _a[0].token;
|
|
43
|
-
if (!gasToken || !isSwapStep(lastStep)) {
|
|
51
|
+
if (!account.isActive || !gasToken || !isSwapStep(lastStep)) {
|
|
44
52
|
return true;
|
|
45
53
|
}
|
|
46
54
|
const balance = Big((_c = (_b = toChainTokenBalances === null || toChainTokenBalances === void 0 ? void 0 : toChainTokenBalances.find((t) => t.address === gasToken.address)) === null || _b === void 0 ? void 0 : _b.amount) !== null && _c !== void 0 ? _c : 0);
|
|
47
55
|
const gasEstimate = (_d = lastStep.estimate.gasCosts) === null || _d === void 0 ? void 0 : _d[0].amount;
|
|
48
56
|
const requiredAmount = Big(gasEstimate || 0).div(Math.pow(10, ((_f = (_e = lastStep.estimate.gasCosts) === null || _e === void 0 ? void 0 : _e[0].token.decimals) !== null && _f !== void 0 ? _f : 0)));
|
|
49
57
|
return balance.gt(0) && balance.gte(requiredAmount);
|
|
50
|
-
}, [lastStep, toChainTokenBalances]);
|
|
58
|
+
}, [account.isActive, lastStep, toChainTokenBalances]);
|
|
51
59
|
const hasSufficientBalance = useMemo(() => {
|
|
52
60
|
var _a, _b;
|
|
53
|
-
if (!fromToken || !fromAmount) {
|
|
61
|
+
if (!account.isActive || !fromToken || !fromAmount) {
|
|
54
62
|
return true;
|
|
55
63
|
}
|
|
56
64
|
const balance = Big((_b = (_a = fromChainTokenBalances === null || fromChainTokenBalances === void 0 ? void 0 : fromChainTokenBalances.find((t) => t.address === fromToken)) === null || _a === void 0 ? void 0 : _a.amount) !== null && _b !== void 0 ? _b : 0);
|
|
57
65
|
return Big(fromAmount).lte(balance);
|
|
58
|
-
}, [fromAmount, fromChainTokenBalances, fromToken]);
|
|
66
|
+
}, [account.isActive, fromAmount, fromChainTokenBalances, fromToken]);
|
|
59
67
|
return {
|
|
60
68
|
hasGasOnStartChain,
|
|
61
69
|
hasGasOnCrossChain,
|
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { useCallback, useEffect, useRef } from 'react';
|
|
11
11
|
import { useMutation } from 'react-query';
|
|
12
12
|
import shallow from 'zustand/shallow';
|
|
13
|
-
import { LiFi } from '../lifi';
|
|
13
|
+
import { LiFi } from '../config/lifi';
|
|
14
14
|
import { useWallet } from '../providers/WalletProvider';
|
|
15
15
|
import { useRouteStore } from '../stores';
|
|
16
16
|
import { deepClone } from '../utils/deepClone';
|
package/hooks/useSwapRoutes.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const useSwapRoutes: () => {
|
|
|
2
2
|
routes: import("@lifi/types").Route[] | undefined;
|
|
3
3
|
isLoading: boolean;
|
|
4
4
|
isFetching: boolean;
|
|
5
|
+
isFetched: boolean;
|
|
5
6
|
dataUpdatedAt: number;
|
|
6
7
|
refetchTime: number;
|
|
7
8
|
refetch: <TPageData>(options?: (import("react-query").RefetchOptions & import("react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("react-query").QueryObserverResult<import("@lifi/types").RoutesResponse, unknown>>;
|
package/hooks/useSwapRoutes.js
CHANGED
|
@@ -7,11 +7,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import Big from 'big.js';
|
|
10
11
|
import { useEffect } from 'react';
|
|
11
12
|
import { useWatch } from 'react-hook-form';
|
|
12
13
|
import { useQuery, useQueryClient } from 'react-query';
|
|
13
14
|
import { useDebouncedWatch, useToken } from '.';
|
|
14
|
-
import { LiFi } from '../lifi';
|
|
15
|
+
import { LiFi } from '../config/lifi';
|
|
15
16
|
import { SwapFormKey } from '../providers/SwapFormProvider';
|
|
16
17
|
import { useWallet } from '../providers/WalletProvider';
|
|
17
18
|
import { useCurrentRoute, useSettings } from '../stores';
|
|
@@ -37,8 +38,9 @@ export const useSwapRoutes = () => {
|
|
|
37
38
|
});
|
|
38
39
|
const [fromTokenAmount] = useDebouncedWatch([SwapFormKey.FromAmount], 250);
|
|
39
40
|
const { token } = useToken(fromChainId, fromTokenAddress);
|
|
40
|
-
const isEnabled =
|
|
41
|
-
|
|
41
|
+
const isEnabled =
|
|
42
|
+
// Boolean(account.address) &&
|
|
43
|
+
!isNaN(fromChainId) &&
|
|
42
44
|
!isNaN(toChainId) &&
|
|
43
45
|
Boolean(fromTokenAddress) &&
|
|
44
46
|
Boolean(toTokenAddress) &&
|
|
@@ -62,13 +64,11 @@ export const useSwapRoutes = () => {
|
|
|
62
64
|
const refetchInterval = previousDataUpdatedAt
|
|
63
65
|
? Math.min(Math.abs(refetchTime - (Date.now() - previousDataUpdatedAt)), refetchTime)
|
|
64
66
|
: refetchTime;
|
|
65
|
-
const { data, isLoading, isFetching, dataUpdatedAt, refetch } = useQuery(queryKey, ({ queryKey: [_, address, fromChainId, fromTokenAddress, fromTokenAmount, toChainId, toTokenAddress, slippage, enabledBridges, enabledExchanges, routePriority,], signal, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
const { data, isLoading, isFetching, isFetched, dataUpdatedAt, refetch } = useQuery(queryKey, ({ queryKey: [_, address, fromChainId, fromTokenAddress, fromTokenAmount, toChainId, toTokenAddress, slippage, enabledBridges, enabledExchanges, routePriority,], signal, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
68
|
var _b;
|
|
67
69
|
return LiFi.getRoutes({
|
|
68
70
|
fromChainId,
|
|
69
|
-
|
|
70
|
-
fromAmount: (Number(fromTokenAmount) *
|
|
71
|
-
Math.pow(10, ((_b = token === null || token === void 0 ? void 0 : token.decimals) !== null && _b !== void 0 ? _b : 0))).toFixed(0),
|
|
71
|
+
fromAmount: Big(Number(fromTokenAmount) * Math.pow(10, ((_b = token === null || token === void 0 ? void 0 : token.decimals) !== null && _b !== void 0 ? _b : 0))).toString(),
|
|
72
72
|
fromTokenAddress,
|
|
73
73
|
toChainId,
|
|
74
74
|
toTokenAddress,
|
|
@@ -105,6 +105,7 @@ export const useSwapRoutes = () => {
|
|
|
105
105
|
routes: data === null || data === void 0 ? void 0 : data.routes,
|
|
106
106
|
isLoading: isEnabled && isLoading,
|
|
107
107
|
isFetching,
|
|
108
|
+
isFetched,
|
|
108
109
|
dataUpdatedAt,
|
|
109
110
|
refetchTime,
|
|
110
111
|
refetch,
|
package/hooks/useTokenBalance.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { useCallback } from 'react';
|
|
11
11
|
import { useQuery, useQueryClient } from 'react-query';
|
|
12
|
-
import { LiFi } from '../lifi';
|
|
12
|
+
import { LiFi } from '../config/lifi';
|
|
13
13
|
import { useWallet } from '../providers/WalletProvider';
|
|
14
14
|
import { formatTokenAmount } from '../utils/format';
|
|
15
15
|
import { useToken } from './useToken';
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { useQuery } from 'react-query';
|
|
11
|
-
import { LiFi } from '../lifi';
|
|
11
|
+
import { LiFi } from '../config/lifi';
|
|
12
12
|
import { useWallet } from '../providers/WalletProvider';
|
|
13
13
|
import { formatTokenAmount } from '../utils/format';
|
|
14
14
|
import { useChains } from './useChains';
|
package/hooks/useTokens.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { useQuery } from 'react-query';
|
|
11
|
-
import { LiFi } from '../lifi';
|
|
11
|
+
import { LiFi } from '../config/lifi';
|
|
12
12
|
export const useTokens = (selectedChainId) => {
|
|
13
13
|
const { data: tokens, isLoading, isFetching, } = useQuery(['tokens', selectedChainId], () => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
14
|
var _a;
|
package/hooks/useTools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
import { useQuery } from 'react-query';
|
|
3
|
-
import { LiFi } from '../lifi';
|
|
3
|
+
import { LiFi } from '../config/lifi';
|
|
4
4
|
import { useSettingsStore } from '../stores';
|
|
5
5
|
export const useTools = () => {
|
|
6
6
|
const initializeTools = useSettingsStore((state) => state.initializeTools);
|
package/i18n/en/translation.json
CHANGED
|
@@ -68,14 +68,22 @@
|
|
|
68
68
|
"fundsReceived": "You now have {{amount}} {{tokenSymbol}} in your wallet on {{chainName}} chain."
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
|
+
"info": {
|
|
72
|
+
"title": {
|
|
73
|
+
"routeNotFound": "No routes available"
|
|
74
|
+
},
|
|
75
|
+
"message": {
|
|
76
|
+
"routeNotFound": "Try another \"from\" and \"to\" token combination."
|
|
77
|
+
}
|
|
78
|
+
},
|
|
71
79
|
"warning": {
|
|
72
80
|
"title": {
|
|
73
81
|
"insufficientGas": "Insufficient gas"
|
|
74
82
|
},
|
|
75
83
|
"message": {
|
|
76
|
-
"insufficientFunds": "You don't have enough funds for this transaction on the start
|
|
77
|
-
"insufficientGasOnStartChain": "You need to have enough gas to pay for this transaction on the start
|
|
78
|
-
"insufficientGasOnDestinationChain": "You need to have enough gas to pay for this transaction on the destination
|
|
84
|
+
"insufficientFunds": "You don't have enough funds for this transaction on the start \"from\" chain.",
|
|
85
|
+
"insufficientGasOnStartChain": "You need to have enough gas to pay for this transaction on the start \"from\" chain.",
|
|
86
|
+
"insufficientGasOnDestinationChain": "You need to have enough gas to pay for this transaction on the destination \"to\" chain."
|
|
79
87
|
}
|
|
80
88
|
},
|
|
81
89
|
"error": {
|
package/i18n/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/widget",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@emotion/styled": "^11.9.3",
|
|
42
42
|
"@ethersproject/experimental": "^5.6.3",
|
|
43
43
|
"@ethersproject/providers": "^5.6.8",
|
|
44
|
-
"@lifi/sdk": "^1.0.
|
|
44
|
+
"@lifi/sdk": "^1.0.2",
|
|
45
45
|
"@lifi/wallet-management": "^1.1.1",
|
|
46
46
|
"@mui/icons-material": "^5.8.4",
|
|
47
47
|
"@mui/lab": "^5.0.0-alpha.90",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@sentry/react": "^7.6.0",
|
|
51
51
|
"@sentry/tracing": "^7.6.0",
|
|
52
52
|
"big.js": "^6.2.1",
|
|
53
|
-
"i18next": "^21.8.
|
|
53
|
+
"i18next": "^21.8.14",
|
|
54
54
|
"immer": "^9.0.15",
|
|
55
55
|
"react": "^18.2.0",
|
|
56
56
|
"react-dom": "^18.2.0",
|
|
57
57
|
"react-hook-form": "^7.33.1",
|
|
58
|
-
"react-i18next": "^11.18.
|
|
58
|
+
"react-i18next": "^11.18.1",
|
|
59
59
|
"react-query": "^4.0.0-beta.23",
|
|
60
60
|
"react-resize-detector": "^7.1.2",
|
|
61
61
|
"react-router-dom": "^6.3.0",
|
|
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box } from '@mui/material';
|
|
3
3
|
import { InsufficientGasOrFundsMessage } from '../../components/InsufficientGasOrFundsMessage';
|
|
4
4
|
import { SelectChainAndToken } from '../../components/SelectChainAndToken';
|
|
5
|
-
import { SwapButton } from '../../components/SwapButton';
|
|
6
5
|
import { SwapInProgress } from '../../components/SwapInProgress';
|
|
7
6
|
import { SwapInput } from '../../components/SwapInput';
|
|
8
7
|
import { SwapRoutes } from '../../components/SwapRoutes';
|
|
9
8
|
import { FormContainer } from './MainPage.style';
|
|
9
|
+
import { MainSwapButton } from './MainSwapButton';
|
|
10
10
|
export const MainPage = () => {
|
|
11
|
-
return (_jsxs(FormContainer, Object.assign({ disableGutters: true }, { children: [_jsx(SwapInProgress, { mx: 3, mt: 2, mb: 1 }), _jsx(SelectChainAndToken, { mt: 2, mx: 3, mb: 3 }), _jsx(Box, Object.assign({ mx: 3, mb: 3 }, { children: _jsx(SwapInput, { formType: "from" }) })), _jsx(SwapRoutes, { mx: 3, mb: 3 }), _jsx(InsufficientGasOrFundsMessage, { mx: 3, mb: 3 }), _jsx(Box, Object.assign({ mx: 3, mb: 1 }, { children: _jsx(
|
|
11
|
+
return (_jsxs(FormContainer, Object.assign({ disableGutters: true }, { children: [_jsx(SwapInProgress, { mx: 3, mt: 2, mb: 1 }), _jsx(SelectChainAndToken, { mt: 2, mx: 3, mb: 3 }), _jsx(Box, Object.assign({ mx: 3, mb: 3 }, { children: _jsx(SwapInput, { formType: "from" }) })), _jsx(SwapRoutes, { mx: 3, mb: 3 }), _jsx(InsufficientGasOrFundsMessage, { mx: 3, mb: 3 }), _jsx(Box, Object.assign({ mx: 3, mb: 1 }, { children: _jsx(MainSwapButton, {}) }))] })));
|
|
12
12
|
};
|
|
@@ -8,4 +8,4 @@ export declare const FormContainer: import("@emotion/styled").StyledComponent<{
|
|
|
8
8
|
sx?: import("@mui/material").SxProps<import("@mui/material").Theme> | undefined;
|
|
9
9
|
} & import("@mui/material/OverridableComponent").CommonProps & Omit<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof import("react").HTMLAttributes<HTMLDivElement>> & {
|
|
10
10
|
ref?: import("react").RefObject<HTMLDivElement> | ((instance: HTMLDivElement | null) => void) | null | undefined;
|
|
11
|
-
}, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "maxWidth" | "fixed" | "disableGutters"> & import("@mui/system").MUIStyledCommonProps<import("@mui/
|
|
11
|
+
}, keyof import("@mui/material/OverridableComponent").CommonProps | "children" | "sx" | "maxWidth" | "fixed" | "disableGutters"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { useNavigate } from 'react-router-dom';
|
|
12
|
+
import { SwapButton } from '../../components/SwapButton';
|
|
13
|
+
import { useSwapRoutes } from '../../hooks';
|
|
14
|
+
import { useCurrentRoute, useSetExecutableRoute } from '../../stores';
|
|
15
|
+
import { routes } from '../../utils/routes';
|
|
16
|
+
export const MainSwapButton = () => {
|
|
17
|
+
const navigate = useNavigate();
|
|
18
|
+
const [currentRoute] = useCurrentRoute();
|
|
19
|
+
const setExecutableRoute = useSetExecutableRoute();
|
|
20
|
+
const { routes: swapRoutes, isLoading, isFetching } = useSwapRoutes();
|
|
21
|
+
const handleClick = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
if (currentRoute &&
|
|
23
|
+
(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.some((route) => route.id === currentRoute.id))) {
|
|
24
|
+
setExecutableRoute(currentRoute);
|
|
25
|
+
navigate(routes.swap, {
|
|
26
|
+
state: { routeId: currentRoute.id },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return _jsx(SwapButton, { onClick: handleClick, loading: isLoading || isFetching });
|
|
31
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const ToggleButton: import("@emotion/styled").StyledComponent<{
|
|
3
3
|
children?: import("react").ReactNode;
|
|
4
4
|
classes?: Partial<import("@mui/material").ToggleButtonClasses> | undefined;
|
|
5
|
-
color?: "success" | "
|
|
5
|
+
color?: "success" | "info" | "warning" | "error" | "primary" | "secondary" | "standard" | undefined;
|
|
6
6
|
disabled?: boolean | undefined;
|
|
7
7
|
disableFocusRipple?: boolean | undefined;
|
|
8
8
|
fullWidth?: boolean | undefined;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const LinkButton: import("@emotion/styled").StyledComponent<{
|
|
3
3
|
children?: import("react").ReactNode;
|
|
4
4
|
classes?: Partial<import("@mui/material").IconButtonClasses> | undefined;
|
|
5
|
-
color?: "inherit" | "default" | "success" | "
|
|
5
|
+
color?: "inherit" | "default" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
6
6
|
disabled?: boolean | undefined;
|
|
7
7
|
disableFocusRipple?: boolean | undefined;
|
|
8
8
|
edge?: false | "end" | "start" | undefined;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from '@mui/material';
|
|
2
3
|
import { Fragment } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
5
6
|
import { InsufficientGasOrFundsMessage } from '../../components/InsufficientGasOrFundsMessage';
|
|
6
|
-
import {
|
|
7
|
+
import { SwapButton } from '../../components/SwapButton';
|
|
8
|
+
import { useRouteExecution } from '../../hooks';
|
|
7
9
|
import { StatusBottomSheet } from './StatusBottomSheet';
|
|
8
10
|
import { StepDivider } from './StepDivider';
|
|
9
11
|
import { StepItem } from './StepItem';
|
|
@@ -12,14 +14,29 @@ export const SwapPage = () => {
|
|
|
12
14
|
const { t } = useTranslation();
|
|
13
15
|
const { state } = useLocation();
|
|
14
16
|
const navigate = useNavigate();
|
|
15
|
-
const { hasGasOnStartChain, hasGasOnCrossChain, hasSufficientBalance } = useHasSufficientBalance();
|
|
16
17
|
const { route, status, executeRoute, restartRoute, removeRoute } = useRouteExecution(state.routeId);
|
|
17
18
|
const handleRemoveRoute = () => {
|
|
18
19
|
removeRoute();
|
|
19
20
|
navigate(-1);
|
|
20
21
|
};
|
|
21
|
-
const
|
|
22
|
+
const handleSwapClick = () => {
|
|
23
|
+
if (status === 'idle') {
|
|
24
|
+
executeRoute();
|
|
25
|
+
}
|
|
26
|
+
if (status === 'error') {
|
|
27
|
+
restartRoute();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
// eslint-disable-next-line consistent-return
|
|
31
|
+
const getSwapButtonText = () => {
|
|
32
|
+
if (status === 'idle') {
|
|
33
|
+
return t('button.startSwap');
|
|
34
|
+
}
|
|
35
|
+
if (status === 'error') {
|
|
36
|
+
return t('button.restartSwap');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
22
39
|
return (_jsxs(Container, { children: [route === null || route === void 0 ? void 0 : route.steps.map((step, index, steps) => (_jsxs(Fragment, { children: [_jsx(StepItem, { step: step, fromToken: index === 0
|
|
23
40
|
? Object.assign(Object.assign({}, route.fromToken), { amount: route.fromAmount }) : undefined, toToken: index === steps.length - 1
|
|
24
|
-
? Object.assign(Object.assign({}, route.toToken), { amount: route.toAmount }) : undefined }), steps.length > 1 && index !== steps.length - 1 ? (_jsx(StepDivider, {})) : null] }, step.id))), _jsx(InsufficientGasOrFundsMessage, { mt: 2 }), status === 'idle' ? (_jsx(
|
|
41
|
+
? Object.assign(Object.assign({}, route.toToken), { amount: route.toAmount }) : undefined }), steps.length > 1 && index !== steps.length - 1 ? (_jsx(StepDivider, {})) : null] }, step.id))), _jsx(InsufficientGasOrFundsMessage, { mt: 2 }), status === 'idle' || status === 'error' ? (_jsx(Box, Object.assign({ mt: 2 }, { children: _jsx(SwapButton, { onClick: handleSwapClick, text: getSwapButtonText() }) }))) : null, status === 'error' ? (_jsx(Button, Object.assign({ variant: "outlined", disableElevation: true, fullWidth: true, onClick: handleRemoveRoute }, { children: t('button.removeSwap') }))) : null, _jsx(StatusBottomSheet, { status: status, route: route })] }));
|
|
25
42
|
};
|
|
@@ -12,7 +12,7 @@ export declare const Container: import("@emotion/styled").StyledComponent<{
|
|
|
12
12
|
export declare const Button: import("@emotion/styled").StyledComponent<{
|
|
13
13
|
children?: import("react").ReactNode;
|
|
14
14
|
classes?: Partial<import("@mui/material").ButtonClasses> | undefined;
|
|
15
|
-
color?: "inherit" | "success" | "
|
|
15
|
+
color?: "inherit" | "success" | "info" | "warning" | "error" | "primary" | "secondary" | undefined;
|
|
16
16
|
disabled?: boolean | undefined;
|
|
17
17
|
disableElevation?: boolean | undefined;
|
|
18
18
|
disableFocusRipple?: boolean | undefined;
|
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
3
|
import { useNavigate } from 'react-router-dom';
|
|
4
|
-
import { SwapRouteCard } from '../../components/SwapRouteCard';
|
|
4
|
+
import { SwapRouteCard, SwapRouteCardSkeleton, SwapRouteNotFoundCard, } from '../../components/SwapRouteCard';
|
|
5
5
|
import { useSwapRoutes } from '../../hooks';
|
|
6
6
|
import { useCurrentRoute, useSetExecutableRoute } from '../../stores';
|
|
7
7
|
import { routes } from '../../utils/routes';
|
|
8
8
|
import { Stack } from './SwapRoutesPage.style';
|
|
9
9
|
export const SwapRoutesPage = () => {
|
|
10
10
|
const navigate = useNavigate();
|
|
11
|
-
const { routes: swapRoutes, isLoading, isFetching } = useSwapRoutes();
|
|
11
|
+
const { routes: swapRoutes, isLoading, isFetching, isFetched, } = useSwapRoutes();
|
|
12
12
|
const [currentRoute] = useCurrentRoute();
|
|
13
13
|
const setExecutableRoute = useSetExecutableRoute();
|
|
14
|
-
if (!(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && !isLoading && !isFetching) {
|
|
15
|
-
// TODO: make no routes message
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
14
|
const handleRouteClick = (route) => {
|
|
19
15
|
setExecutableRoute(route);
|
|
20
16
|
navigate(routes.swap, { state: { routeId: route.id }, replace: true });
|
|
21
17
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && !isLoading && !isFetching) {
|
|
20
|
+
navigate(routes.home);
|
|
21
|
+
}
|
|
22
|
+
// redirect to the home page if no routes are found on page reload
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, []);
|
|
25
|
+
const routeNotFound = !(swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.length) && isFetched;
|
|
26
|
+
return (_jsx(Stack, Object.assign({ direction: "column", spacing: 2 }, { children: routeNotFound ? (_jsx(SwapRouteNotFoundCard, { minWidth: "100%", dense: true })) : isLoading || isFetching ? (Array.from({ length: 3 }).map((_, index) => (_jsx(SwapRouteCardSkeleton, { minWidth: "100%", dense: true }, index)))) : (swapRoutes === null || swapRoutes === void 0 ? void 0 : swapRoutes.map((route, index) => (_jsx(SwapRouteCard, { route: route, active: (currentRoute === null || currentRoute === void 0 ? void 0 : currentRoute.id) === route.id, onClick: () => handleRouteClick(route) }, route.id)))) })));
|
|
28
27
|
};
|
|
@@ -11,7 +11,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import { ChainId, getChainByKey } from '@lifi/sdk';
|
|
14
|
-
import {
|
|
14
|
+
import { updateLiFiConfig } from '@lifi/widget/config/lifi';
|
|
15
|
+
import { createContext, useContext, useEffect, useMemo } from 'react';
|
|
15
16
|
const stub = () => {
|
|
16
17
|
throw new Error('You forgot to wrap your component in <WidgetProvider>.');
|
|
17
18
|
};
|
|
@@ -21,7 +22,7 @@ const initialContext = {
|
|
|
21
22
|
const WidgetContext = createContext(initialContext);
|
|
22
23
|
export const useWidgetConfig = () => useContext(WidgetContext);
|
|
23
24
|
export const WidgetProvider = (_a) => {
|
|
24
|
-
var { children } = _a, _b = _a.config, _c = _b === void 0 ? {} : _b, { fromChain, fromToken, toChain, toToken } = _c, config = __rest(_c, ["fromChain", "fromToken", "toChain", "toToken"]);
|
|
25
|
+
var { children } = _a, _b = _a.config, _c = _b === void 0 ? {} : _b, { fromChain, fromToken, toChain, toToken, integrator } = _c, config = __rest(_c, ["fromChain", "fromToken", "toChain", "toToken", "integrator"]);
|
|
25
26
|
const value = useMemo(() => {
|
|
26
27
|
try {
|
|
27
28
|
return Object.assign(Object.assign({}, config), { fromChain: typeof fromChain === 'number'
|
|
@@ -39,5 +40,12 @@ export const WidgetProvider = (_a) => {
|
|
|
39
40
|
return config;
|
|
40
41
|
}
|
|
41
42
|
}, [config, fromChain, fromToken, toChain, toToken]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
updateLiFiConfig({
|
|
45
|
+
defaultRouteOptions: {
|
|
46
|
+
integrator: integrator !== null && integrator !== void 0 ? integrator : window.location.hostname,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}, [integrator]);
|
|
42
50
|
return (_jsx(WidgetContext.Provider, Object.assign({ value: value }, { children: children })));
|
|
43
51
|
};
|
package/types/widget.d.ts
CHANGED
package/utils/format.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Big from 'big.js';
|
|
2
|
-
// JavaScript numbers use exponential notation for positive exponents of 21 and above.
|
|
3
|
-
Big.PE =
|
|
2
|
+
// JavaScript numbers use exponential notation for positive exponents of 21 and above. We need more.
|
|
3
|
+
Big.PE = 42;
|
|
4
4
|
// JavaScript numbers use exponential notation for negative exponents of -7 and below. We need more.
|
|
5
|
-
Big.NE = -
|
|
5
|
+
Big.NE = -42;
|
|
6
6
|
/**
|
|
7
7
|
* Format token amount to at least 4 decimals.
|
|
8
8
|
* @param amount amount to format.
|
package/lifi.d.ts
DELETED