@rango-dev/widget-embedded 0.20.1-next.20 → 0.20.1-next.22

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 (119) hide show
  1. package/dist/components/AppRouter.d.ts.map +1 -1
  2. package/dist/components/AppRoutes.d.ts.map +1 -1
  3. package/dist/components/BlockchainList/BlockchainList.styles.d.ts +161 -1
  4. package/dist/components/BlockchainList/BlockchainList.styles.d.ts.map +1 -1
  5. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts +0 -1
  6. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts.map +1 -1
  7. package/dist/components/HeaderButtons/HomeButtons.d.ts.map +1 -1
  8. package/dist/components/Layout/Layout.d.ts +2 -3
  9. package/dist/components/Layout/Layout.d.ts.map +1 -1
  10. package/dist/components/Layout/Layout.helpers.d.ts +2 -0
  11. package/dist/components/Layout/Layout.helpers.d.ts.map +1 -0
  12. package/dist/components/Layout/Layout.styles.d.ts +2 -4
  13. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  14. package/dist/components/Layout/Layout.types.d.ts +6 -3
  15. package/dist/components/Layout/Layout.types.d.ts.map +1 -1
  16. package/dist/components/Layout/PageContainer.d.ts +166 -0
  17. package/dist/components/Layout/PageContainer.d.ts.map +1 -0
  18. package/dist/components/Layout/ScrollableArea.d.ts +164 -0
  19. package/dist/components/Layout/ScrollableArea.d.ts.map +1 -0
  20. package/dist/components/Layout/index.d.ts +2 -0
  21. package/dist/components/Layout/index.d.ts.map +1 -1
  22. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  23. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
  24. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts +0 -161
  25. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts.map +1 -1
  26. package/dist/components/SettingsContainer/index.d.ts +1 -1
  27. package/dist/components/SettingsContainer/index.d.ts.map +1 -1
  28. package/dist/components/SwapDetails/SwapDetails.Placeholder.d.ts.map +1 -1
  29. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  30. package/dist/components/SwapDetails/SwapDetails.styles.d.ts +161 -1
  31. package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
  32. package/dist/components/TokenList/TokenList.styles.d.ts.map +1 -1
  33. package/dist/constants/searchParams.d.ts +6 -6
  34. package/dist/constants/searchParams.d.ts.map +1 -1
  35. package/dist/containers/App/App.styles.d.ts.map +1 -1
  36. package/dist/containers/QuoteInfo/QuoteInfo.d.ts +1 -1
  37. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  38. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts +0 -324
  39. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts.map +1 -1
  40. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +0 -7
  41. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  42. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  43. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  44. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
  45. package/dist/hooks/useSyncUrlAndStore/index.d.ts +2 -0
  46. package/dist/hooks/useSyncUrlAndStore/index.d.ts.map +1 -0
  47. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts +2 -0
  48. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts.map +1 -0
  49. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts +4 -0
  50. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.d.ts.map +1 -0
  51. package/dist/index.js +2 -2
  52. package/dist/index.js.map +4 -4
  53. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  54. package/dist/pages/HistoryPage.d.ts.map +1 -1
  55. package/dist/pages/Home.d.ts.map +1 -1
  56. package/dist/pages/LanguagePage.d.ts.map +1 -1
  57. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  58. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  59. package/dist/pages/SettingsPage.d.ts.map +1 -1
  60. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  61. package/dist/pages/ThemePage.d.ts.map +1 -1
  62. package/dist/pages/WalletsPage.d.ts.map +1 -1
  63. package/dist/utils/quote.d.ts +0 -1
  64. package/dist/utils/quote.d.ts.map +1 -1
  65. package/dist/utils/ui.d.ts +2 -0
  66. package/dist/utils/ui.d.ts.map +1 -1
  67. package/package.json +3 -3
  68. package/src/components/AppRouter.tsx +1 -8
  69. package/src/components/AppRoutes.tsx +11 -0
  70. package/src/components/BlockchainList/BlockchainList.styles.ts +4 -3
  71. package/src/components/BlockchainList/BlockchainList.tsx +1 -1
  72. package/src/components/HeaderButtons/HeaderButtons.types.ts +0 -1
  73. package/src/components/HeaderButtons/HomeButtons.tsx +1 -2
  74. package/src/components/Layout/Layout.helpers.ts +16 -0
  75. package/src/components/Layout/Layout.styles.ts +17 -31
  76. package/src/components/Layout/Layout.tsx +24 -27
  77. package/src/components/Layout/Layout.types.ts +9 -8
  78. package/src/components/Layout/PageContainer.tsx +24 -0
  79. package/src/components/Layout/ScrollableArea.tsx +11 -0
  80. package/src/components/Layout/index.ts +2 -0
  81. package/src/components/NotificationContent/NotificationContent.tsx +0 -3
  82. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts +0 -1
  83. package/src/components/SettingsContainer/SettingsContainer.style.ts +0 -5
  84. package/src/components/SettingsContainer/index.ts +0 -1
  85. package/src/components/SwapDetails/SwapDetails.Placeholder.tsx +0 -1
  86. package/src/components/SwapDetails/SwapDetails.styles.ts +5 -6
  87. package/src/components/SwapDetails/SwapDetails.tsx +3 -5
  88. package/src/components/TokenList/TokenList.styles.ts +2 -0
  89. package/src/components/TokenList/TokenList.tsx +1 -1
  90. package/src/constants/searchParams.ts +6 -6
  91. package/src/containers/App/App.styles.ts +2 -0
  92. package/src/containers/QuoteInfo/QuoteInfo.styles.ts +0 -15
  93. package/src/containers/QuoteInfo/QuoteInfo.tsx +30 -77
  94. package/src/containers/QuoteInfo/QuoteInfo.types.ts +0 -7
  95. package/src/containers/Wallets/Wallets.tsx +0 -2
  96. package/src/hooks/useSwapInput.ts +6 -1
  97. package/src/hooks/useSyncStoresWithConfig.ts +3 -17
  98. package/src/hooks/useSyncUrlAndStore/index.ts +1 -0
  99. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts +35 -0
  100. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +135 -0
  101. package/src/pages/ConfirmSwapPage.tsx +52 -47
  102. package/src/pages/HistoryPage.tsx +5 -17
  103. package/src/pages/Home.tsx +44 -43
  104. package/src/pages/LanguagePage.tsx +3 -4
  105. package/src/pages/LiquiditySourcePage.tsx +3 -4
  106. package/src/pages/SelectBlockchainPage.tsx +38 -38
  107. package/src/pages/SelectSwapItemsPage.tsx +40 -38
  108. package/src/pages/SettingsPage.tsx +3 -4
  109. package/src/pages/SwapDetailsPage.tsx +21 -7
  110. package/src/pages/ThemePage.tsx +3 -4
  111. package/src/pages/WalletsPage.tsx +12 -13
  112. package/src/utils/quote.ts +0 -27
  113. package/src/utils/ui.ts +20 -0
  114. package/dist/components/UpdateUrl.d.ts +0 -2
  115. package/dist/components/UpdateUrl.d.ts.map +0 -1
  116. package/dist/store/ui.d.ts +0 -22
  117. package/dist/store/ui.d.ts.map +0 -1
  118. package/src/components/UpdateUrl.tsx +0 -158
  119. package/src/store/ui.ts +0 -21
@@ -1,8 +1,8 @@
1
1
  export enum SearchParams {
2
- 'FROM_CHAIN' = 'fromBlockchain',
3
- 'FROM_TOKEN' = 'fromToken',
4
- 'TO_CHAIN' = 'toBlockchain',
5
- 'TO_TOKEN' = 'toToken',
6
- 'FROM_AMOUNT' = 'fromAmount',
7
- 'AUTO_CONNECT' = 'autoConnect',
2
+ FROM_BLOCKCHAIN = 'fromBlockchain',
3
+ FROM_TOKEN = 'fromToken',
4
+ TO_BLOCKCHAIN = 'toBlockchain',
5
+ TO_TOKEN = 'toToken',
6
+ FROM_AMOUNT = 'fromAmount',
7
+ AUTO_CONNECT = 'autoConnect',
8
8
  }
@@ -6,6 +6,8 @@ export const MainContainer = styled('div', {
6
6
  alignItems: 'center',
7
7
  fontFamily: '$widget',
8
8
  boxSizing: 'border-box',
9
+ textAlign: 'left',
10
+
9
11
  '& *, *::before, *::after': {
10
12
  boxSizing: 'inherit',
11
13
  },
@@ -1,26 +1,11 @@
1
1
  import { styled } from '@rango-dev/ui';
2
2
 
3
- export const PositionTopAlerts = styled('div', {
4
- paddingBottom: '$10',
5
- });
6
-
7
3
  export const QuoteContainer = styled('div', {
8
4
  width: '100%',
9
5
  '& .position-top__skeleton': {
10
6
  paddingTop: '$10',
11
7
  },
12
8
  });
13
-
14
- export const SkeletonContainer = styled('div', {
15
- variants: {
16
- paddingTop: {
17
- true: {
18
- paddingTop: '$10',
19
- },
20
- },
21
- },
22
- });
23
-
24
9
  export const FooterStepAlarm = styled('div', {
25
10
  paddingBottom: '$15',
26
11
  });
@@ -1,36 +1,16 @@
1
1
  import type { PropTypes } from './QuoteInfo.types';
2
2
 
3
- import { Divider } from '@rango-dev/ui';
4
3
  import React from 'react';
5
4
 
6
5
  import { Quote } from '../../components/Quote';
7
6
  import { QuoteSkeleton } from '../../components/QuoteSkeleton';
8
- import { QuoteWarningsAndErrors } from '../../components/QuoteWarningsAndErrors';
9
7
  import { useQuoteStore } from '../../store/quote';
10
8
  import { QuoteErrorType } from '../../types';
11
9
 
12
- import {
13
- PositionTopAlerts,
14
- QuoteContainer,
15
- SkeletonContainer,
16
- } from './QuoteInfo.styles';
10
+ import { QuoteContainer } from './QuoteInfo.styles';
17
11
 
18
12
  export function QuoteInfo(props: PropTypes) {
19
- const {
20
- quote,
21
- type,
22
- loading,
23
- error,
24
- warning,
25
- refetchQuote,
26
- showWarningModal,
27
- onOpenWarningModal,
28
- onCloseWarningModal,
29
- onConfirmWarningModal,
30
- onChangeSettings,
31
- expanded = false,
32
- alertPosition = 'bottom',
33
- } = props;
13
+ const { quote, type, loading, error, warning, expanded = false } = props;
34
14
  const { inputAmount, inputUsdValue, outputUsdValue, outputAmount } =
35
15
  useQuoteStore();
36
16
 
@@ -41,59 +21,32 @@ export function QuoteInfo(props: PropTypes) {
41
21
 
42
22
  const showQuote = !noResult && quote && quote.result && !loading;
43
23
 
44
- const quoteWarningsAndErrors = (warning || error) && (
45
- <QuoteWarningsAndErrors
46
- warning={warning}
47
- error={error}
48
- loading={loading}
49
- refetchQuote={refetchQuote}
50
- showWarningModal={showWarningModal}
51
- onOpenWarningModal={onOpenWarningModal}
52
- onCloseWarningModal={onCloseWarningModal}
53
- onConfirmWarningModal={onConfirmWarningModal}
54
- onChangeSettings={onChangeSettings}
55
- />
56
- );
57
- return (
58
- <>
59
- {loading && (
60
- <QuoteContainer>
61
- <SkeletonContainer paddingTop={alertPosition === 'top'}>
62
- <QuoteSkeleton type={type} expanded={expanded} />
63
- </SkeletonContainer>
64
- </QuoteContainer>
65
- )}
66
-
67
- {alertPosition === 'top' && (
68
- <PositionTopAlerts>{quoteWarningsAndErrors}</PositionTopAlerts>
69
- )}
70
- {showQuote ? (
71
- <QuoteContainer>
72
- <Quote
73
- quote={quote}
74
- error={error}
75
- warning={warning}
76
- type={type}
77
- expanded={expanded}
78
- recommended={true}
79
- input={{
80
- value: inputAmount,
81
- usdValue: inputUsdValue?.toString() ?? '',
82
- }}
83
- output={{
84
- value: outputAmount?.toString() ?? '',
85
- usdValue: outputUsdValue?.toString() ?? '',
86
- }}
87
- />
88
- </QuoteContainer>
89
- ) : null}
90
-
91
- {alertPosition === 'bottom' && (
92
- <>
93
- {!warning && !error && <Divider size={16} />}
94
- {quoteWarningsAndErrors}
95
- </>
96
- )}
97
- </>
98
- );
24
+ if (loading) {
25
+ return (
26
+ <QuoteContainer>
27
+ <QuoteSkeleton type={type} expanded={expanded} />
28
+ </QuoteContainer>
29
+ );
30
+ }
31
+
32
+ return showQuote ? (
33
+ <QuoteContainer>
34
+ <Quote
35
+ quote={quote}
36
+ error={error}
37
+ warning={warning}
38
+ type={type}
39
+ expanded={expanded}
40
+ recommended={true}
41
+ input={{
42
+ value: inputAmount,
43
+ usdValue: inputUsdValue?.toString() ?? '',
44
+ }}
45
+ output={{
46
+ value: outputAmount?.toString() ?? '',
47
+ usdValue: outputUsdValue?.toString() ?? '',
48
+ }}
49
+ />
50
+ </QuoteContainer>
51
+ ) : null;
99
52
  }
@@ -10,11 +10,4 @@ export type PropTypes = {
10
10
  warning: QuoteWarning | null;
11
11
  autoScrollOnExpanding?: boolean;
12
12
  expanded?: boolean;
13
- alertPosition?: 'top' | 'bottom';
14
- refetchQuote: () => void;
15
- showWarningModal: boolean;
16
- onOpenWarningModal: () => void;
17
- onCloseWarningModal: () => void;
18
- onConfirmWarningModal: () => void;
19
- onChangeSettings: () => void;
20
13
  };
@@ -13,7 +13,6 @@ import { Events, Provider } from '@rango-dev/wallets-react';
13
13
  import { isEvmBlockchain } from 'rango-sdk';
14
14
  import React, { createContext, useEffect, useRef, useState } from 'react';
15
15
 
16
- import { useSyncStoresWithConfig } from '../../hooks/useSyncStoresWithConfig';
17
16
  import { useWalletProviders } from '../../hooks/useWalletProviders';
18
17
  import { AppStoreProvider, useAppStore } from '../../store/AppStore';
19
18
  import { useWalletsStore } from '../../store/wallets';
@@ -39,7 +38,6 @@ function Main(props: PropsWithChildren<PropTypes>) {
39
38
  const { providers } = useWalletProviders(props.config.wallets, walletOptions);
40
39
  const { connectWallet, disconnectWallet } = useWalletsStore();
41
40
  const onConnectWalletHandler = useRef<OnConnectHandler>();
42
- useSyncStoresWithConfig();
43
41
 
44
42
  useEffect(() => {
45
43
  void fetchMeta().catch(console.log);
@@ -59,8 +59,9 @@ export function useSwapInput(): UseSwapInput {
59
59
  affiliateRef,
60
60
  affiliateWallets,
61
61
  disabledLiquiditySources,
62
+ fetchStatus,
62
63
  } = useAppStore();
63
- const [loading, setLoading] = useState(false);
64
+ const [loading, setLoading] = useState(true);
64
65
  const [error, setError] = useState<QuoteError | null>(null);
65
66
  const [warning, setWarning] = useState<QuoteWarning | null>(null);
66
67
  const userSlippage = customSlippage ?? slippage;
@@ -148,6 +149,9 @@ export function useSwapInput(): UseSwapInput {
148
149
  );
149
150
 
150
151
  useEffect(() => {
152
+ if (fetchStatus !== 'success') {
153
+ return;
154
+ }
151
155
  if (!isPositiveNumber(inputAmount) || inputUsdValue?.eq(0)) {
152
156
  resetState(false);
153
157
  cancelFetch();
@@ -175,6 +179,7 @@ export function useSwapInput(): UseSwapInput {
175
179
  });
176
180
  return cancelFetch;
177
181
  }, [
182
+ fetchStatus,
178
183
  inputAmount,
179
184
  fromToken?.symbol,
180
185
  fromToken?.address,
@@ -1,6 +1,6 @@
1
1
  import type { Asset } from 'rango-sdk';
2
2
 
3
- import { useEffect, useLayoutEffect, useRef } from 'react';
3
+ import { useEffect, useRef } from 'react';
4
4
 
5
5
  import { useAppStore } from '../store/AppStore';
6
6
  import { useQuoteStore } from '../store/quote';
@@ -44,14 +44,7 @@ export function useSyncStoresWithConfig() {
44
44
  setInputAmount(config?.amount?.toString() || '');
45
45
  }, [config?.amount]);
46
46
 
47
- /*
48
- * We update quote tokens in two scenarios.
49
- * If default values exist in widget config or search parameters exist in URL.
50
- * The logic for updating quote store exists in two useEffect in two locations, and they run in order.If default tokens for quote exist in widget config and also exist in URL, widget config values take precedence over URL values, and URL search parameters don’t affect the widget.
51
- * Using useLayoutEffect causes widget config values to apply first.
52
- * We may consider replacing this with a better solution in the future.
53
- */
54
- useLayoutEffect(() => {
47
+ useEffect(() => {
55
48
  if (fetchMetaStatus === 'success') {
56
49
  const chain = blockchains.find(
57
50
  (chain) => chain.name === config?.from?.blockchain
@@ -100,14 +93,7 @@ export function useSyncStoresWithConfig() {
100
93
  }
101
94
  }, [toTokensConfig, toBlockchainsConfig]);
102
95
 
103
- /*
104
- * We update quote tokens in two scenarios.
105
- * If default values exist in widget config or search parameters exist in URL.
106
- * The logic for updating quote store exists in two useEffect in two locations, and they run in order.If default tokens for quote exist in widget config and also exist in URL, widget config values take precedence over URL values, and URL search parameters don’t affect the widget.
107
- * Using useLayoutEffect causes widget config values to apply first.
108
- * We may consider replacing this with a better solution in the future.
109
- */
110
- useLayoutEffect(() => {
96
+ useEffect(() => {
111
97
  if (fetchMetaStatus === 'success') {
112
98
  const chain = blockchains.find(
113
99
  (chain) => chain.name === config?.to?.blockchain
@@ -0,0 +1 @@
1
+ export { useSyncUrlAndStore } from './useSyncUrlAndStore';
@@ -0,0 +1,35 @@
1
+ import type { BlockchainMeta, Token } from 'rango-sdk';
2
+
3
+ export function searchParamToToken(
4
+ tokens: Token[],
5
+ searchParam: string | null,
6
+ chain: BlockchainMeta | null
7
+ ): Token | null {
8
+ if (!chain) {
9
+ return null;
10
+ }
11
+ return (
12
+ tokens.find((token) => {
13
+ const symbolAndAddress = searchParam?.split('--');
14
+ if (symbolAndAddress?.length === 1) {
15
+ return (
16
+ token.symbol === symbolAndAddress[0] &&
17
+ token.address === null &&
18
+ token.blockchain === chain.name
19
+ );
20
+ }
21
+ return (
22
+ token.symbol === symbolAndAddress?.[0] &&
23
+ token.address === symbolAndAddress?.[1] &&
24
+ token.blockchain === chain.name
25
+ );
26
+ }) || null
27
+ );
28
+ }
29
+
30
+ export function tokenToSearchParam(token: Token | null): string | undefined {
31
+ if (token) {
32
+ return `${token.symbol}${token.address ? `--${token.address}` : ''}`;
33
+ }
34
+ return undefined;
35
+ }
@@ -0,0 +1,135 @@
1
+ import { useEffect } from 'react';
2
+ import {
3
+ useInRouterContext,
4
+ useLocation,
5
+ useSearchParams,
6
+ } from 'react-router-dom';
7
+
8
+ import { SearchParams } from '../../constants/searchParams';
9
+ import { useAppStore } from '../../store/AppStore';
10
+ import { useQuoteStore } from '../../store/quote';
11
+
12
+ import {
13
+ searchParamToToken,
14
+ tokenToSearchParam,
15
+ } from './useSyncUrlAndStore.helpers';
16
+
17
+ export function useSyncUrlAndStore() {
18
+ const location = useLocation();
19
+ const [searchParams, setSearchParams] = useSearchParams();
20
+ const {
21
+ fromBlockchain,
22
+ toBlockchain,
23
+ fromToken,
24
+ toToken,
25
+ inputAmount,
26
+ setFromBlockchain,
27
+ setToBlockchain,
28
+ setFromToken,
29
+ setToToken,
30
+ setInputAmount,
31
+ } = useQuoteStore();
32
+ const fetchMetaStatus = useAppStore().fetchStatus;
33
+ const blockchains = useAppStore().blockchains();
34
+ const tokens = useAppStore().tokens();
35
+ const isInRouterContext = useInRouterContext();
36
+
37
+ const getUrlSearchParams = () => {
38
+ const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
39
+ const fromBlockchain = searchParams.get(SearchParams.FROM_BLOCKCHAIN);
40
+ const fromToken = searchParams.get(SearchParams.FROM_TOKEN);
41
+ const toBlockchain = searchParams.get(SearchParams.TO_BLOCKCHAIN);
42
+ const toToken = searchParams.get(SearchParams.TO_TOKEN);
43
+ const autoConnect = searchParams.get(SearchParams.AUTO_CONNECT);
44
+
45
+ return {
46
+ fromAmount,
47
+ fromBlockchain,
48
+ fromToken,
49
+ toBlockchain,
50
+ toToken,
51
+ autoConnect,
52
+ };
53
+ };
54
+
55
+ const updateUrlSearchParams = (
56
+ searchParams: Record<string, string | undefined>
57
+ ) => {
58
+ for (const property in searchParams) {
59
+ if (!searchParams[property]) {
60
+ delete searchParams[property];
61
+ }
62
+ }
63
+ setSearchParams(searchParams as Record<string, string>, { replace: true });
64
+ };
65
+
66
+ useEffect(() => {
67
+ const { autoConnect } = getUrlSearchParams();
68
+ if (isInRouterContext && fetchMetaStatus === 'success') {
69
+ updateUrlSearchParams({
70
+ [SearchParams.FROM_BLOCKCHAIN]: fromBlockchain?.name,
71
+ [SearchParams.FROM_TOKEN]: tokenToSearchParam(fromToken),
72
+ [SearchParams.TO_BLOCKCHAIN]: toBlockchain?.name,
73
+ [SearchParams.TO_TOKEN]: tokenToSearchParam(toToken),
74
+ [SearchParams.FROM_AMOUNT]: inputAmount,
75
+ [SearchParams.AUTO_CONNECT]: autoConnect ?? undefined,
76
+ });
77
+ }
78
+ }, [
79
+ location.pathname,
80
+ inputAmount,
81
+ fromBlockchain,
82
+ fromToken,
83
+ toBlockchain,
84
+ toToken,
85
+ ]);
86
+
87
+ useEffect(() => {
88
+ if (!isInRouterContext) {
89
+ return;
90
+ }
91
+ const searchParams = getUrlSearchParams();
92
+ if (searchParams.fromAmount) {
93
+ setInputAmount(searchParams.fromAmount);
94
+ }
95
+ if (fetchMetaStatus === 'success') {
96
+ const fromBlockchain = blockchains.find(
97
+ (blockchain) => blockchain.name === searchParams.fromBlockchain
98
+ );
99
+ const fromToken = searchParamToToken(
100
+ tokens,
101
+ searchParams.fromToken,
102
+ fromBlockchain ?? null
103
+ );
104
+ const toBlockchain = blockchains.find(
105
+ (blockchain) => blockchain.name === searchParams.toBlockchain
106
+ );
107
+ const toToken = searchParamToToken(
108
+ tokens,
109
+ searchParams.toToken,
110
+ toBlockchain ?? null
111
+ );
112
+ if (!!fromBlockchain) {
113
+ setFromBlockchain(fromBlockchain);
114
+ if (!!fromToken) {
115
+ setFromToken({
116
+ token: fromToken,
117
+ meta: {
118
+ blockchains: blockchains,
119
+ tokens: tokens,
120
+ },
121
+ });
122
+ }
123
+ }
124
+ if (!!toBlockchain) {
125
+ setToBlockchain(toBlockchain);
126
+ if (!!toToken) {
127
+ setToToken({
128
+ token: toToken,
129
+ meta: { blockchains: blockchains, tokens: tokens },
130
+ });
131
+ }
132
+ }
133
+ }
134
+ }, [fetchMetaStatus]);
135
+ }
@@ -20,32 +20,24 @@ import {
20
20
  } from '@rango-dev/ui';
21
21
  import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
22
22
  import { flushSync } from 'react-dom';
23
- import { useNavigate } from 'react-router-dom';
23
+ import { useLocation, useNavigate } from 'react-router-dom';
24
24
 
25
25
  import { getRequiredWallets } from '../components/ConfirmWalletsModal/ConfirmWallets.helpers';
26
26
  import { ConfirmWalletsModal } from '../components/ConfirmWalletsModal/ConfirmWalletsModal';
27
27
  import { HeaderButton } from '../components/HeaderButtons/HeaderButtons.styles';
28
28
  import { RefreshButton } from '../components/HeaderButtons/RefreshButton';
29
- import { Layout } from '../components/Layout';
29
+ import { Layout, PageContainer } from '../components/Layout';
30
+ import { QuoteWarningsAndErrors } from '../components/QuoteWarningsAndErrors';
30
31
  import { navigationRoutes } from '../constants/navigationRoutes';
31
32
  import { getQuoteUpdateWarningMessage } from '../constants/warnings';
32
33
  import { QuoteInfo } from '../containers/QuoteInfo';
33
34
  import { useConfirmSwap } from '../hooks/useConfirmSwap';
34
35
  import { useAppStore } from '../store/AppStore';
35
36
  import { useQuoteStore } from '../store/quote';
36
- import { useUiStore } from '../store/ui';
37
37
  import { useWalletsStore } from '../store/wallets';
38
38
  import { QuoteWarningType } from '../types';
39
39
  import { getContainer } from '../utils/common';
40
-
41
- const Container = styled('div', {
42
- position: 'relative',
43
- width: '100%',
44
-
45
- '& .quote-update__alert': {
46
- paddingTop: '$10',
47
- },
48
- });
40
+ import { joinList } from '../utils/ui';
49
41
 
50
42
  const Buttons = styled('div', {
51
43
  width: '100%',
@@ -88,12 +80,12 @@ export function ConfirmSwapPage() {
88
80
  quoteWarningsConfirmed,
89
81
  } = useQuoteStore();
90
82
  const navigate = useNavigate();
83
+ const location = useLocation();
91
84
  const [dbErrorMessage, setDbErrorMessage] = useState<string>('');
92
85
 
93
86
  const { connectedWallets } = useWalletsStore();
94
87
  const showWalletsOnInit = !quoteWalletsConfirmed;
95
88
  const [showWallets, setShowWallets] = useState(false);
96
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
97
89
  const disabledLiquiditySources = useAppStore().disabledLiquiditySources;
98
90
  const prevDisabledLiquiditySources = useRef(disabledLiquiditySources);
99
91
  const { manager } = useManager();
@@ -128,7 +120,6 @@ export function ConfirmSwapPage() {
128
120
  { swapDetails: confirmSwapResult.swap },
129
121
  { id: confirmSwapResult.swap.requestId }
130
122
  );
131
- setSelectedSwap(confirmSwapResult.swap.requestId);
132
123
 
133
124
  const swap_url = `../${navigationRoutes.swaps}/${confirmSwapResult.swap.requestId}`;
134
125
  navigate(swap_url, {
@@ -259,10 +250,49 @@ export function ConfirmSwapPage() {
259
250
 
260
251
  useLayoutEffect(() => {
261
252
  if (!quote) {
262
- navigate(`../`);
253
+ navigate(`../${location.search}`);
263
254
  }
264
255
  }, []);
265
256
 
257
+ const quoteWarning = confirmSwapResult.warnings?.quote ?? null;
258
+ const quoteError = confirmSwapResult.error;
259
+ const alerts = [];
260
+ if (dbErrorMessage) {
261
+ alerts.push(<Alert type="error" variant="alarm" title={dbErrorMessage} />);
262
+ }
263
+
264
+ if (confirmSwapResult.warnings?.quoteUpdate) {
265
+ alerts.push(
266
+ <Alert
267
+ variant="alarm"
268
+ type="warning"
269
+ title={
270
+ confirmSwapResult.warnings.quoteUpdate &&
271
+ getQuoteUpdateWarningMessage(confirmSwapResult.warnings.quoteUpdate)
272
+ }
273
+ />
274
+ );
275
+ }
276
+
277
+ if (quoteWarning || quoteError) {
278
+ alerts.push(
279
+ <QuoteWarningsAndErrors
280
+ warning={quoteWarning}
281
+ error={quoteError}
282
+ loading={fetchingConfirmationQuote}
283
+ refetchQuote={onRefresh}
284
+ showWarningModal={showQuoteWarningModal}
285
+ onOpenWarningModal={() => setShowQuoteWarningModal(true)}
286
+ onCloseWarningModal={() => setShowQuoteWarningModal(false)}
287
+ onConfirmWarningModal={async () => {
288
+ setShowQuoteWarningModal(false);
289
+ await addNewSwap();
290
+ }}
291
+ onChangeSettings={() => navigate(navigationRoutes.settings)}
292
+ />
293
+ );
294
+ }
295
+
266
296
  return (
267
297
  <Layout
268
298
  header={{
@@ -319,7 +349,7 @@ export function ConfirmSwapPage() {
319
349
  />
320
350
  )}
321
351
 
322
- <Container>
352
+ <PageContainer>
323
353
  <div className={descriptionStyles()}>
324
354
  <Typography variant="title" size="small">
325
355
  {i18n.t('You get')}
@@ -336,45 +366,20 @@ export function ConfirmSwapPage() {
336
366
  />
337
367
  </div>
338
368
  </div>
339
- {dbErrorMessage && (
340
- <>
341
- <Alert type="error" variant="alarm" title={dbErrorMessage} />
342
- <Divider size={12} />
343
- </>
344
- )}
345
- {confirmSwapResult.warnings?.quoteUpdate && (
346
- <div className="quote-update__alert">
347
- <Alert
348
- variant="alarm"
349
- type="warning"
350
- title={
351
- confirmSwapResult.warnings.quoteUpdate &&
352
- getQuoteUpdateWarningMessage(
353
- confirmSwapResult.warnings.quoteUpdate
354
- )
355
- }
356
- />
357
- </div>
358
- )}
369
+ <Divider size="12" />
370
+
371
+ {joinList(alerts, <Divider size={10} />)}
372
+ {alerts.length > 0 ? <Divider size={10} /> : null}
373
+
359
374
  <QuoteInfo
360
375
  quote={quote}
361
376
  type="swap-preview"
362
377
  expanded={true}
363
- alertPosition="top"
364
378
  error={confirmSwapResult.error}
365
379
  loading={fetchingConfirmationQuote}
366
380
  warning={confirmSwapResult.warnings?.quote ?? null}
367
- refetchQuote={onRefresh}
368
- showWarningModal={showQuoteWarningModal}
369
- onOpenWarningModal={() => setShowQuoteWarningModal(true)}
370
- onCloseWarningModal={() => setShowQuoteWarningModal(false)}
371
- onConfirmWarningModal={async () => {
372
- setShowQuoteWarningModal(false);
373
- await addNewSwap();
374
- }}
375
- onChangeSettings={() => navigate('../' + navigationRoutes.settings)}
376
381
  />
377
- </Container>
382
+ </PageContainer>
378
383
  </Layout>
379
384
  );
380
385
  }