@rango-dev/widget-embedded 0.1.10-next.93 → 0.1.10-next.95

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 (80) hide show
  1. package/dist/QueueManager.d.ts.map +1 -1
  2. package/dist/components/AppRoutes.d.ts +5 -1
  3. package/dist/components/AppRoutes.d.ts.map +1 -1
  4. package/dist/components/ConfirmSwapErrors.d.ts +3 -2
  5. package/dist/components/ConfirmSwapErrors.d.ts.map +1 -1
  6. package/dist/components/ConfirmSwapWarnings.d.ts +3 -2
  7. package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -1
  8. package/dist/components/Layout.d.ts +1 -1
  9. package/dist/components/Layout.d.ts.map +1 -1
  10. package/dist/components/SwitchFromAndTo.d.ts +1 -1
  11. package/dist/components/SwitchFromAndTo.d.ts.map +1 -1
  12. package/dist/components/UpdateUrl.d.ts +1 -1
  13. package/dist/components/UpdateUrl.d.ts.map +1 -1
  14. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  15. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -1
  16. package/dist/hooks/useConfirmSwap.d.ts +11 -0
  17. package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
  18. package/dist/hooks/usePrevious.d.ts +1 -1
  19. package/dist/hooks/usePrevious.d.ts.map +1 -1
  20. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  21. package/dist/pages/Home.d.ts.map +1 -1
  22. package/dist/pages/SelectChainPage.d.ts.map +1 -1
  23. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  24. package/dist/pages/SettingsPage.d.ts.map +1 -1
  25. package/dist/pages/WalletsPage.d.ts.map +1 -1
  26. package/dist/store/bestRoute.d.ts +25 -0
  27. package/dist/store/bestRoute.d.ts.map +1 -1
  28. package/dist/store/settings.d.ts +15 -0
  29. package/dist/store/settings.d.ts.map +1 -1
  30. package/dist/store/wallets.d.ts.map +1 -1
  31. package/dist/types/index.d.ts +1 -0
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/{store/confirmSwap.d.ts → types/routing.d.ts} +14 -5
  34. package/dist/types/routing.d.ts.map +1 -0
  35. package/dist/utils/numbers.d.ts +1 -1
  36. package/dist/utils/numbers.d.ts.map +1 -1
  37. package/dist/utils/routing.d.ts +11 -5
  38. package/dist/utils/routing.d.ts.map +1 -1
  39. package/dist/utils/swap.d.ts +4 -3
  40. package/dist/utils/swap.d.ts.map +1 -1
  41. package/dist/utils/wallets.d.ts +7 -2
  42. package/dist/utils/wallets.d.ts.map +1 -1
  43. package/dist/widget-embedded.cjs.development.js +575 -479
  44. package/dist/widget-embedded.cjs.development.js.map +1 -1
  45. package/dist/widget-embedded.cjs.production.min.js +575 -479
  46. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  47. package/dist/widget-embedded.esm.js +576 -480
  48. package/dist/widget-embedded.esm.js.map +1 -1
  49. package/package.json +3 -3
  50. package/src/QueueManager.tsx +1 -0
  51. package/src/components/AppRoutes.tsx +54 -21
  52. package/src/components/ChangeSlippageButton.tsx +1 -1
  53. package/src/components/ConfirmSwapErrors.tsx +1 -1
  54. package/src/components/ConfirmSwapWarnings.tsx +1 -4
  55. package/src/components/Header.tsx +1 -1
  56. package/src/components/Layout.tsx +3 -3
  57. package/src/components/UpdateUrl.tsx +13 -22
  58. package/src/components/warnings/BalanceWarnings.tsx +27 -4
  59. package/src/components/warnings/ConfirmSwapExtraMessages.tsx +7 -1
  60. package/src/components/warnings/HighSlippageWarning.tsx +1 -1
  61. package/src/components/warnings/MinRequiredSlippage.tsx +2 -2
  62. package/src/hooks/useConfirmSwap.ts +260 -0
  63. package/src/pages/ConfirmSwapPage.tsx +17 -8
  64. package/src/pages/ConfirmWalletsPage.tsx +1 -1
  65. package/src/pages/Home.tsx +0 -1
  66. package/src/pages/SelectChainPage.tsx +2 -7
  67. package/src/pages/SelectTokenPage.tsx +22 -57
  68. package/src/pages/SettingsPage.tsx +8 -9
  69. package/src/pages/WalletsPage.tsx +16 -6
  70. package/src/store/bestRoute.ts +82 -37
  71. package/src/store/settings.ts +2 -2
  72. package/src/store/wallets.ts +26 -0
  73. package/src/types/index.ts +1 -0
  74. package/src/types/routing.ts +60 -0
  75. package/src/utils/numbers.ts +38 -17
  76. package/src/utils/routing.ts +115 -24
  77. package/src/utils/swap.ts +20 -12
  78. package/src/utils/wallets.ts +117 -73
  79. package/dist/store/confirmSwap.d.ts.map +0 -1
  80. package/src/store/confirmSwap.ts +0 -342
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.1.10-next.93",
3
+ "version": "0.1.10-next.95",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -41,8 +41,8 @@
41
41
  "immer": "^9.0.19",
42
42
  "mitt": "^3.0.0",
43
43
  "parcel": "^2.8.0",
44
- "rango-sdk": "^0.1.18",
45
- "rango-types": "^0.1.22",
44
+ "rango-sdk": "^0.1.19",
45
+ "rango-types": "^0.1.23",
46
46
  "react": "^18.2.0",
47
47
  "react-dom": "^18.2.0",
48
48
  "react-i18next": "^12.2.0",
@@ -80,6 +80,7 @@ function QueueManager(props: PropsWithChildren<{}>) {
80
80
 
81
81
  return (
82
82
  <ManagerProvider
83
+ //@ts-ignore
83
84
  queuesDefs={[swapQueueDef]}
84
85
  context={context}
85
86
  onPersistedDataLoaded={(_manager) => {}}
@@ -13,48 +13,73 @@ import { ConfirmWalletsPage } from '../pages/ConfirmWalletsPage';
13
13
  import { SwapDetailsPage } from '../pages/SwapDetailsPage';
14
14
  import { Configs } from '../types';
15
15
 
16
- export const AppRoutes = ({
17
- fromChains = 'all',
18
- toChains = 'all',
19
- fromTokens = 'all',
20
- toTokens = 'all',
21
- liquiditySources = 'all',
22
- wallets = 'all',
23
- title,
24
- multiWallets = true,
25
- titleSize,
26
- titleWeight,
27
- }: Configs) =>
28
- useRoutes([
16
+ interface PropTypes {
17
+ configs?: Configs;
18
+ }
19
+
20
+ export function AppRoutes(props: PropTypes) {
21
+ const { configs } = props;
22
+
23
+ return useRoutes([
29
24
  {
30
25
  path: navigationRoutes.home,
31
26
  element: (
32
- <Home title={title} titleSize={titleSize} titleWeight={titleWeight} />
27
+ <Home
28
+ title={configs?.title}
29
+ titleSize={configs?.titleSize}
30
+ titleWeight={configs?.titleWeight}
31
+ />
33
32
  ),
34
33
  },
35
34
  {
36
35
  path: navigationRoutes.fromChain,
37
- element: <SelectChainPage type="from" supportedChains={fromChains} />,
36
+ element: (
37
+ <SelectChainPage
38
+ type="from"
39
+ supportedChains={configs?.fromChains || 'all'}
40
+ />
41
+ ),
38
42
  },
39
43
  {
40
44
  path: navigationRoutes.toChain,
41
- element: <SelectChainPage type="to" supportedChains={toChains} />,
45
+ element: (
46
+ <SelectChainPage
47
+ type="to"
48
+ supportedChains={configs?.toChains || 'all'}
49
+ />
50
+ ),
42
51
  },
43
52
  {
44
53
  path: navigationRoutes.fromToken + '/*',
45
- element: <SelectTokenPage type="from" supportedTokens={fromTokens} />,
54
+ element: (
55
+ <SelectTokenPage
56
+ type="from"
57
+ supportedTokens={configs?.fromTokens || 'all'}
58
+ />
59
+ ),
46
60
  },
47
61
  {
48
62
  path: navigationRoutes.toToken,
49
- element: <SelectTokenPage type="to" supportedTokens={toTokens} />,
63
+ element: (
64
+ <SelectTokenPage
65
+ type="to"
66
+ supportedTokens={configs?.toTokens || 'all'}
67
+ />
68
+ ),
50
69
  },
51
70
  {
52
71
  path: navigationRoutes.settings,
53
- element: <SettingsPage supportedSwappers={liquiditySources} />,
72
+ element: (
73
+ <SettingsPage supportedSwappers={configs?.liquiditySources || 'all'} />
74
+ ),
54
75
  },
55
76
  {
56
77
  path: navigationRoutes.liquiditySources,
57
- element: <LiquiditySourcePage supportedSwappers={liquiditySources} />,
78
+ element: (
79
+ <LiquiditySourcePage
80
+ supportedSwappers={configs?.liquiditySources || 'all'}
81
+ />
82
+ ),
58
83
  },
59
84
  { path: navigationRoutes.swaps, element: <HistoryPage /> },
60
85
  {
@@ -64,9 +89,17 @@ export const AppRoutes = ({
64
89
  {
65
90
  path: navigationRoutes.wallets,
66
91
  element: (
67
- <WalletsPage supportedWallets={wallets} multiWallets={multiWallets} />
92
+ <WalletsPage
93
+ supportedWallets={configs?.wallets || 'all'}
94
+ multiWallets={
95
+ typeof configs?.multiWallets === 'undefined'
96
+ ? true
97
+ : configs.multiWallets
98
+ }
99
+ />
68
100
  ),
69
101
  },
70
102
  { path: navigationRoutes.confirmSwap, element: <ConfirmSwapPage /> },
71
103
  { path: navigationRoutes.confirmWallets, element: <ConfirmWalletsPage /> },
72
104
  ]);
105
+ }
@@ -15,7 +15,7 @@ export function ChangeSlippageButton() {
15
15
  type="primary"
16
16
  variant="contained"
17
17
  size="small"
18
- onClick={navigate.bind(null, navigationRoutes.settings)}
18
+ onClick={() => navigate(navigationRoutes.settings)}
19
19
  >
20
20
  Change Slippage
21
21
  </StyledButton>
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Typography } from '@rango-dev/ui';
3
- import { ConfirmSwapError, ConfirmSwapErrorTypes } from '../store/confirmSwap';
3
+ import { ConfirmSwapError, ConfirmSwapErrorTypes } from '../types';
4
4
  import { MinRequiredSlippage } from './warnings/MinRequiredSlippage';
5
5
 
6
6
  export function ConfirmSwapErrors(errors: ConfirmSwapError[]) {
@@ -1,9 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Typography } from '@rango-dev/ui';
3
- import {
4
- ConfirmSwapWarnings,
5
- ConfirmSwapWarningTypes,
6
- } from '../store/confirmSwap';
3
+ import { ConfirmSwapWarningTypes, ConfirmSwapWarnings } from '../types';
7
4
  import { BalanceWarnings } from './warnings/BalanceWarnings';
8
5
 
9
6
  export function ConfirmSwapWarnings(warnings: ConfirmSwapWarnings[]) {
@@ -29,7 +29,7 @@ export function Header(props: PropTypes) {
29
29
  return (
30
30
  <HeaderContainer>
31
31
  <Typography variant="h4" className={titleStyle()}>
32
- {t(title.toLocaleLowerCase()) || title}
32
+ {title ? t(title.toLocaleLowerCase()) : ''}
33
33
  </Typography>
34
34
  <HeaderButtons onClickRefresh={onClickRefresh} />
35
35
  </HeaderContainer>
@@ -30,7 +30,7 @@ const WalletImage = styled('img', {
30
30
  });
31
31
 
32
32
  export type LayoutProps = {
33
- configs: Configs;
33
+ configs?: Configs;
34
34
  };
35
35
 
36
36
  export function Layout({ configs }: LayoutProps) {
@@ -58,7 +58,7 @@ export function Layout({ configs }: LayoutProps) {
58
58
  setToToken(configs?.toToken || null);
59
59
  }, [configs?.toChain, configs?.toToken]);
60
60
  useEffect(() => {
61
- setInputAmount(configs?.fromAmount.toString() || null);
61
+ setInputAmount(configs?.fromAmount?.toString() || '');
62
62
  }, [configs?.fromAmount]);
63
63
 
64
64
  useEffect(() => {
@@ -90,7 +90,7 @@ export function Layout({ configs }: LayoutProps) {
90
90
  </Typography>
91
91
  </Button>
92
92
  </Header>
93
- <AppRoutes {...configs} />
93
+ <AppRoutes configs={configs} />
94
94
  </>
95
95
  );
96
96
  }
@@ -1,4 +1,3 @@
1
- import { Token } from 'rango-sdk';
2
1
  import { useEffect, useRef } from 'react';
3
2
  import {
4
3
  createSearchParams,
@@ -10,23 +9,7 @@ import { useMetaStore } from '../store/meta';
10
9
  import { SearchParams } from '../constants/searchParams';
11
10
  import { navigationRoutes } from '../constants/navigationRoutes';
12
11
  import { useUiStore } from '../store/ui';
13
-
14
- function searchParamsToToken(
15
- tokens: Token[],
16
- searchParams: string | null
17
- ): Token | null {
18
- return (
19
- tokens.find((token) => {
20
- const symbolAndAddress = searchParams?.split('--');
21
- if (symbolAndAddress?.length === 1)
22
- return token.symbol === symbolAndAddress[0] && token.address === null;
23
- return (
24
- token.symbol === symbolAndAddress?.[0] &&
25
- token.address === symbolAndAddress?.[1]
26
- );
27
- }) || null
28
- );
29
- }
12
+ import { searchParamsToToken } from '../utils/routing';
30
13
 
31
14
  export function UpdateUrl() {
32
15
  const firstRender = useRef(true);
@@ -142,19 +125,27 @@ export function UpdateUrl() {
142
125
 
143
126
  useEffect(() => {
144
127
  if (loadingStatus === 'success') {
145
- const fronChainString = searchParams.get(SearchParams.FROM_CHAIN);
128
+ const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
146
129
  const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
147
130
  const toChainString = searchParams.get(SearchParams.TO_CHAIN);
148
131
  const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
149
132
  const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
150
133
  const fromChain = blockchains.find(
151
- (blockchain) => blockchain.name === fronChainString
134
+ (blockchain) => blockchain.name === fromChainString
135
+ );
136
+ const fromToken = searchParamsToToken(
137
+ tokens,
138
+ fromTokenString,
139
+ fromChain || null
152
140
  );
153
- const fromToken = searchParamsToToken(tokens, fromTokenString);
154
141
  const toChain = blockchains.find(
155
142
  (blockchain) => blockchain.name === toChainString
156
143
  );
157
- const toToken = searchParamsToToken(tokens, toTokenString);
144
+ const toToken = searchParamsToToken(
145
+ tokens,
146
+ toTokenString,
147
+ toChain || null
148
+ );
158
149
  if (!!fromChain) {
159
150
  setFromChain(fromChain);
160
151
  if (!!fromToken) setFromToken(fromToken);
@@ -1,16 +1,39 @@
1
- import { Typography } from '@rango-dev/ui';
1
+ import { styled, Typography } from '@rango-dev/ui';
2
2
  import React from 'react';
3
3
 
4
4
  interface PropTypes {
5
5
  messages: string[];
6
6
  }
7
7
 
8
+ const List = styled('ul', {
9
+ variants: {
10
+ showListStyle: {
11
+ true: { paddingLeft: '$24' },
12
+ },
13
+ },
14
+ });
15
+
16
+ const ListItem = styled('li', {
17
+ variants: {
18
+ showListStyle: {
19
+ true: { listStyleType: 'disc', listStylePosition: 'outside' },
20
+ },
21
+ },
22
+ });
23
+
24
+ const Message = styled(Typography, {
25
+ display: 'block',
26
+ });
27
+
8
28
  export function BalanceWarnings({ messages }: PropTypes) {
29
+ const showListStyle = messages.length > 1;
9
30
  return (
10
- <div>
31
+ <List showListStyle={showListStyle}>
11
32
  {messages.map((warning) => (
12
- <Typography variant="body2">{warning}</Typography>
33
+ <ListItem showListStyle={showListStyle}>
34
+ <Message variant="body2">{warning}</Message>
35
+ </ListItem>
13
36
  ))}
14
- </div>
37
+ </List>
15
38
  );
16
39
  }
@@ -10,5 +10,11 @@ export function ConfirmSwapExtraMessages(props: PropTypes) {
10
10
  const { selectedSlippage } = props;
11
11
  const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
12
12
 
13
- return <>{highSlippage && <HighSlippageWarning selectedSlippage={selectedSlippage} />}</>;
13
+ return (
14
+ <>
15
+ {highSlippage && (
16
+ <HighSlippageWarning selectedSlippage={selectedSlippage} />
17
+ )}
18
+ </>
19
+ );
14
20
  }
@@ -12,7 +12,7 @@ export function HighSlippageWarning(props: PropTypes) {
12
12
  return (
13
13
  <Alert type="warning">
14
14
  <Typography variant="body2">
15
- slippage is high=&gt; Caution, your slippage is high (=
15
+ Caution, your slippage is high (=
16
16
  {selectedSlippage}). Your trade may be front run.
17
17
  <ChangeSlippageButton />
18
18
  </Typography>
@@ -9,9 +9,9 @@ interface PropTypes {
9
9
  export function MinRequiredSlippage({ minRequiredSlippage }: PropTypes) {
10
10
  return (
11
11
  <Typography variant="body2">
12
- slippage is low =&gt; We recommend you to increase slippage to at least
12
+ We recommend you to increase slippage to at least &nbsp;
13
13
  {minRequiredSlippage}
14
- for this route.
14
+ &nbsp; for this route.
15
15
  <ChangeSlippageButton />
16
16
  </Typography>
17
17
  );
@@ -0,0 +1,260 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { useBestRouteStore } from '../store/bestRoute';
3
+ import { useMetaStore } from '../store/meta';
4
+ import { useSettingsStore } from '../store/settings';
5
+ import { useWalletsStore } from '../store/wallets';
6
+ import {
7
+ ConfirmSwapError,
8
+ ConfirmSwapErrorTypes,
9
+ ConfirmSwapWarningTypes,
10
+ ConfirmSwapWarnings,
11
+ PendingSwapSettings,
12
+ } from '../types';
13
+ import { PendingSwap } from '@rango-dev/ui/dist/containers/History/types';
14
+ import {
15
+ calculatePendingSwap,
16
+ createBestRouteRequestBody,
17
+ getBalanceWarnings,
18
+ getMinRequiredSlippage,
19
+ getOutputRatio,
20
+ getPercentageChange,
21
+ getRouteOutputAmount,
22
+ getWalletsForNewSwap,
23
+ hasProperSlippage,
24
+ isOutputAmountChangedALot,
25
+ outputRatioHasWarning,
26
+ } from '../utils/swap';
27
+ import { httpService } from '../services/httpService';
28
+ import BigNumber from 'bignumber.js';
29
+ import {
30
+ isNumberOfSwapsChanged,
31
+ isRouteChanged,
32
+ isRouteInternalCoinsUpdated,
33
+ isRouteSwappersUpdated,
34
+ } from '../utils/routing';
35
+ import { numberToString } from '../utils/numbers';
36
+ import { BestRouteResponse } from 'rango-sdk';
37
+
38
+ type ConfirmSwap = {
39
+ loading: boolean;
40
+ errors: ConfirmSwapError[];
41
+ warnings: ConfirmSwapWarnings[];
42
+ confirmSwap: (() => Promise<PendingSwap | undefined>) | null;
43
+ };
44
+
45
+ export function useConfirmSwap(): ConfirmSwap {
46
+ const fromToken = useBestRouteStore.use.fromToken();
47
+ const toToken = useBestRouteStore.use.toToken();
48
+ const inputAmount = useBestRouteStore.use.inputAmount();
49
+ const initialRoute = useBestRouteStore.use.bestRoute();
50
+ const setBestRoute = useBestRouteStore.use.setBestRoute();
51
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
52
+ const accounts = useWalletsStore.use.accounts();
53
+ const selectedWallets = useWalletsStore.use.selectedWallets();
54
+ const meta = useMetaStore.use.meta();
55
+ const customSlippage = useSettingsStore.use.customSlippage();
56
+ const slippage = useSettingsStore.use.slippage();
57
+ const disabledLiquiditySources =
58
+ useSettingsStore.use.disabledLiquiditySources();
59
+ const userSlippage = customSlippage || slippage;
60
+ const proceedAnywayRef = useRef(false);
61
+ const confiremedRouteRef = useRef<BestRouteResponse | null>(null);
62
+ let abortControllerRef = useRef<AbortController | null>(null);
63
+
64
+ const [loading, setLoading] = useState(false);
65
+ const [errors, setErrors] = useState<ConfirmSwapError[]>([]);
66
+ const [warnings, setWarnings] = useState<ConfirmSwapWarnings[]>([]);
67
+
68
+ useEffect(() => {
69
+ return () => abortControllerRef.current?.abort();
70
+ }, []);
71
+
72
+ if (!fromToken || !toToken || !inputAmount || !initialRoute)
73
+ return { loading: false, warnings: [], errors: [], confirmSwap: null };
74
+
75
+ const confirmSwap = async (): Promise<PendingSwap | undefined> => {
76
+ if (proceedAnywayRef.current) {
77
+ const swapSettings: PendingSwapSettings = {
78
+ slippage: userSlippage.toString(),
79
+ disabledSwappersGroups: disabledLiquiditySources,
80
+ };
81
+
82
+ if (errors.length > 0) setErrors([]);
83
+ if (warnings.length > 0) setWarnings([]);
84
+ proceedAnywayRef.current = false;
85
+
86
+ if (confiremedRouteRef.current) {
87
+ const newSwap = calculatePendingSwap(
88
+ inputAmount.toString(),
89
+ confiremedRouteRef.current,
90
+ getWalletsForNewSwap(selectedWallets),
91
+ swapSettings,
92
+ false,
93
+ meta
94
+ );
95
+
96
+ return newSwap;
97
+ }
98
+ return;
99
+ }
100
+
101
+ abortControllerRef.current = new AbortController();
102
+
103
+ setLoading(true);
104
+
105
+ const requestBody = createBestRouteRequestBody(
106
+ fromToken,
107
+ toToken,
108
+ inputAmount,
109
+ accounts,
110
+ selectedWallets,
111
+ disabledLiquiditySources,
112
+ userSlippage,
113
+ true
114
+ );
115
+
116
+ try {
117
+ const confiremedRoute = await httpService.getBestRoute(requestBody, {
118
+ signal: abortControllerRef.current?.signal,
119
+ });
120
+
121
+ abortControllerRef.current = null;
122
+
123
+ setLoading(false);
124
+
125
+ if (
126
+ !confiremedRoute.result ||
127
+ !new BigNumber(confiremedRoute.requestAmount).isEqualTo(
128
+ new BigNumber(inputAmount || '-1')
129
+ )
130
+ ) {
131
+ setErrors((prevState) =>
132
+ prevState.concat({
133
+ type: ConfirmSwapErrorTypes.NO_ROUTE,
134
+ })
135
+ );
136
+ return;
137
+ }
138
+
139
+ const confirmSwapState: Omit<ConfirmSwap, 'confirmSwap' | 'loading'> = {
140
+ errors: [],
141
+ warnings: [],
142
+ };
143
+
144
+ const routeChanged = isRouteChanged(initialRoute, confiremedRoute!);
145
+
146
+ if (routeChanged) {
147
+ setBestRoute(confiremedRoute);
148
+ const newRouteOutputUsdValue = new BigNumber(
149
+ confiremedRoute.result?.outputAmount || '0'
150
+ ).multipliedBy(toToken.usdPrice || 0);
151
+
152
+ const outputRatio = getOutputRatio(
153
+ inputUsdValue,
154
+ newRouteOutputUsdValue
155
+ );
156
+ const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio);
157
+
158
+ if (highValueLoss)
159
+ confirmSwapState.errors.push({
160
+ type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS,
161
+ });
162
+ else if (isOutputAmountChangedALot(initialRoute, confiremedRoute))
163
+ confirmSwapState.warnings.push({
164
+ type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
165
+ newOutputAmount: numberToString(
166
+ getRouteOutputAmount(confiremedRoute)
167
+ ),
168
+ percentageChange: numberToString(
169
+ getPercentageChange(
170
+ getRouteOutputAmount(initialRoute),
171
+ getRouteOutputAmount(confiremedRoute)
172
+ ),
173
+ null,
174
+ 2
175
+ ),
176
+ });
177
+ else if (isRouteInternalCoinsUpdated(initialRoute, confiremedRoute))
178
+ confirmSwapState.warnings.push({
179
+ type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED,
180
+ });
181
+ else if (isNumberOfSwapsChanged(initialRoute, confiremedRoute))
182
+ confirmSwapState.warnings.push({
183
+ type: ConfirmSwapWarningTypes.ROUTE_UPDATED,
184
+ });
185
+ else if (isRouteSwappersUpdated(initialRoute, confiremedRoute))
186
+ confirmSwapState.warnings.push({
187
+ type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED,
188
+ });
189
+ }
190
+
191
+ const balanceWarnings = getBalanceWarnings(
192
+ confiremedRoute,
193
+ selectedWallets
194
+ );
195
+ const enoughBalance = balanceWarnings.length === 0;
196
+
197
+ if (!enoughBalance)
198
+ confirmSwapState.warnings.push({
199
+ type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE,
200
+ messages: balanceWarnings,
201
+ });
202
+
203
+ const minRequiredSlippage = getMinRequiredSlippage(initialRoute);
204
+
205
+ if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage))
206
+ confirmSwapState.errors.push({
207
+ type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE,
208
+ minRequiredSlippage,
209
+ });
210
+
211
+ const noErrors = confirmSwapState.errors.length === 0;
212
+ const noWarnings = confirmSwapState.warnings.length === 0;
213
+
214
+ if (
215
+ (noErrors || (!noErrors && proceedAnywayRef.current)) &&
216
+ (noWarnings || (!noWarnings && proceedAnywayRef.current))
217
+ ) {
218
+ const swapSettings: PendingSwapSettings = {
219
+ slippage: userSlippage.toString(),
220
+ disabledSwappersGroups: disabledLiquiditySources,
221
+ };
222
+
223
+ const newSwap = calculatePendingSwap(
224
+ inputAmount.toString(),
225
+ confiremedRoute,
226
+ getWalletsForNewSwap(selectedWallets),
227
+ swapSettings,
228
+ false,
229
+ meta
230
+ );
231
+
232
+ return newSwap;
233
+ } else if (!proceedAnywayRef.current) {
234
+ proceedAnywayRef.current = true;
235
+ setErrors(confirmSwapState.errors);
236
+ setWarnings(confirmSwapState.warnings);
237
+ confiremedRouteRef.current = confiremedRoute;
238
+ }
239
+ return;
240
+ } catch (error) {
241
+ if ((error as any)?.code === 'ERR_CANCELED') {
242
+ return;
243
+ }
244
+
245
+ const status = (error as any)?.response?.status;
246
+
247
+ setLoading(false);
248
+ setErrors([
249
+ {
250
+ type: ConfirmSwapErrorTypes.REQUEST_FAILED,
251
+ status,
252
+ },
253
+ ]);
254
+
255
+ return;
256
+ }
257
+ };
258
+
259
+ return { loading, warnings, errors, confirmSwap };
260
+ }
@@ -6,11 +6,14 @@ import { useSettingsStore } from '../store/settings';
6
6
  import { ConfirmSwapExtraMessages } from '../components/warnings/ConfirmSwapExtraMessages';
7
7
  import { useNavigateBack } from '../hooks/useNavigateBack';
8
8
  import { navigationRoutes } from '../constants/navigationRoutes';
9
- import { confirmSwap, useConfirmSwapStore } from '../store/confirmSwap';
10
9
  import { ConfirmSwapErrors } from '../components/ConfirmSwapErrors';
11
10
  import { ConfirmSwapWarnings } from '../components/ConfirmSwapWarnings';
12
11
  import { useManager } from '@rango-dev/queue-manager-react';
13
12
  import { useUiStore } from '../store/ui';
13
+ import { useConfirmSwap } from '../hooks/useConfirmSwap';
14
+ import { ConfirmSwapErrorTypes } from '../types';
15
+ import { useMetaStore } from '../store/meta';
16
+ import { getBestRouteWithCalculatedFees } from '../utils/routing';
14
17
 
15
18
  export function ConfirmSwapPage() {
16
19
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
@@ -19,18 +22,22 @@ export function ConfirmSwapPage() {
19
22
  const navigate = useNavigate();
20
23
 
21
24
  const bestRoute = useBestRouteStore.use.bestRoute();
25
+ const fetchingBestRoute = useBestRouteStore.use.loading();
26
+ const { tokens } = useMetaStore.use.meta();
22
27
 
23
- const loading = useConfirmSwapStore.use.loading();
24
- const warnings = useConfirmSwapStore.use.warnings();
25
- const errors = useConfirmSwapStore.use.errors();
26
28
  const slippage = useSettingsStore.use.slippage();
27
29
  const customSlippage = useSettingsStore.use.customSlippage();
28
30
  const selectedSlippage = customSlippage || slippage;
31
+ const { loading, errors, warnings, confirmSwap } = useConfirmSwap();
32
+
33
+ const showHighSlippageWarning = !errors.find(
34
+ (error) => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE
35
+ );
29
36
 
30
37
  return (
31
38
  <ConfirmSwap
32
39
  onConfirm={() => {
33
- confirmSwap().then((swap) => {
40
+ confirmSwap?.().then((swap) => {
34
41
  if (swap) {
35
42
  manager?.create('swap', { swapDetails: swap });
36
43
  setSelectedSwap(swap.requestId);
@@ -41,19 +48,21 @@ export function ConfirmSwapPage() {
41
48
  });
42
49
  }}
43
50
  onBack={navigateBackFrom.bind(null, navigationRoutes.confirmSwap)}
44
- bestRoute={bestRoute}
51
+ bestRoute={getBestRouteWithCalculatedFees(bestRoute, tokens)}
45
52
  loading={loading}
46
53
  errors={ConfirmSwapErrors(errors)}
47
54
  warnings={ConfirmSwapWarnings(warnings)}
48
55
  extraMessages={
49
- <ConfirmSwapExtraMessages selectedSlippage={selectedSlippage} />
56
+ showHighSlippageWarning && (
57
+ <ConfirmSwapExtraMessages selectedSlippage={selectedSlippage} />
58
+ )
50
59
  }
51
60
  confirmButtonTitle={
52
61
  warnings.length > 0 || errors.length > 0
53
62
  ? 'Proceed anyway!'
54
63
  : 'Confirm swap!'
55
64
  }
56
- confirmButtonDisabled={errors.length > 0}
65
+ confirmButtonDisabled={fetchingBestRoute}
57
66
  />
58
67
  );
59
68
  }