@rango-dev/widget-embedded 0.20.1-next.1 → 0.20.1-next.10

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 (74) hide show
  1. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -0
  2. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  3. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +159 -0
  4. package/dist/components/HeaderButtons/HeaderButtons.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/HeaderButtons/RefreshButton.d.ts +6 -0
  9. package/dist/components/HeaderButtons/RefreshButton.d.ts.map +1 -0
  10. package/dist/components/Quote/Quote.d.ts.map +1 -1
  11. package/dist/components/Quote/Quote.styles.d.ts +157 -0
  12. package/dist/components/Quote/Quote.styles.d.ts.map +1 -1
  13. package/dist/components/Quote/QuoteSummary.d.ts.map +1 -1
  14. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  15. package/dist/components/SwapDetails/SwapDetails.helpers.d.ts.map +1 -1
  16. package/dist/components/SwapDetailsModal/SwapDetailsCompleteModal.d.ts.map +1 -1
  17. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts +2 -0
  18. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts.map +1 -1
  19. package/dist/components/SwapsGroup/SwapsGroup.d.ts.map +1 -1
  20. package/dist/constants/routing.d.ts +1 -0
  21. package/dist/constants/routing.d.ts.map +1 -1
  22. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  23. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts +2 -2
  24. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  25. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +4 -4
  30. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  31. package/dist/pages/Home.d.ts.map +1 -1
  32. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  33. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  34. package/dist/store/slices/data.d.ts.map +1 -1
  35. package/dist/types/config.d.ts +16 -3
  36. package/dist/types/config.d.ts.map +1 -1
  37. package/dist/utils/configs.d.ts +8 -0
  38. package/dist/utils/configs.d.ts.map +1 -1
  39. package/dist/utils/date.d.ts.map +1 -1
  40. package/dist/utils/numbers.d.ts +1 -5
  41. package/dist/utils/numbers.d.ts.map +1 -1
  42. package/dist/utils/settings.d.ts +1 -1
  43. package/dist/utils/time.d.ts.map +1 -1
  44. package/package.json +7 -7
  45. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +1 -1
  46. package/src/components/HeaderButtons/HeaderButtons.styles.ts +16 -1
  47. package/src/components/HeaderButtons/HeaderButtons.types.ts +0 -1
  48. package/src/components/HeaderButtons/HomeButtons.tsx +20 -33
  49. package/src/components/HeaderButtons/RefreshButton.tsx +81 -0
  50. package/src/components/Quote/Quote.styles.ts +5 -1
  51. package/src/components/Quote/Quote.tsx +53 -15
  52. package/src/components/Quote/QuoteSummary.tsx +20 -4
  53. package/src/components/Slippage/Slippage.tsx +5 -5
  54. package/src/components/SwapDetails/SwapDetails.helpers.tsx +7 -1
  55. package/src/components/SwapDetails/SwapDetails.tsx +21 -1
  56. package/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx +6 -0
  57. package/src/components/SwapDetailsModal/SwapDetailsModal.types.ts +2 -0
  58. package/src/components/SwapsGroup/SwapsGroup.tsx +28 -11
  59. package/src/constants/routing.ts +2 -0
  60. package/src/containers/Wallets/Wallets.tsx +11 -2
  61. package/src/hooks/useSwapInput.ts +6 -2
  62. package/src/hooks/useSyncStoresWithConfig.ts +17 -34
  63. package/src/index.ts +2 -0
  64. package/src/pages/ConfirmSwapPage.tsx +12 -10
  65. package/src/pages/Home.tsx +16 -2
  66. package/src/pages/LiquiditySourcePage.tsx +5 -2
  67. package/src/pages/SelectBlockchainPage.tsx +3 -3
  68. package/src/pages/SelectSwapItemsPage.tsx +5 -1
  69. package/src/store/slices/data.ts +5 -7
  70. package/src/types/config.ts +16 -3
  71. package/src/utils/configs.ts +41 -0
  72. package/src/utils/date.ts +24 -9
  73. package/src/utils/numbers.ts +8 -58
  74. package/src/utils/time.ts +25 -69
@@ -18,6 +18,7 @@ import {
18
18
  useCopyToClipboard,
19
19
  } from '@rango-dev/ui';
20
20
  import { useWallets } from '@rango-dev/wallets-react';
21
+ import BigNumber from 'bignumber.js';
21
22
  import { PendingSwapNetworkStatus } from 'rango-types';
22
23
  import React, { useEffect, useRef, useState } from 'react';
23
24
  import { useNavigate } from 'react-router-dom';
@@ -35,7 +36,9 @@ import {
35
36
  import { useAppStore } from '../../store/AppStore';
36
37
  import { useNotificationStore } from '../../store/notification';
37
38
  import { useQuoteStore } from '../../store/quote';
39
+ import { getContainer } from '../../utils/common';
38
40
  import {
41
+ formatTooltipNumbers,
39
42
  numberToString,
40
43
  secondsToString,
41
44
  totalArrivalTime,
@@ -188,6 +191,16 @@ export function SwapDetails(props: SwapDetailsProps) {
188
191
  USD_VALUE_MAX_DECIMALS
189
192
  );
190
193
 
194
+ const realOutputUsdValue = outputAmount
195
+ ? formatTooltipNumbers(
196
+ new BigNumber(outputAmount).multipliedBy(lastStep.toUsdPrice || 0)
197
+ )
198
+ : '';
199
+
200
+ const realInputUsdValue = formatTooltipNumbers(
201
+ new BigNumber(swap.inputAmount).multipliedBy(firstStep.fromUsdPrice || 0)
202
+ );
203
+
191
204
  const percentageChange = getPriceImpact(inputUsdValue, outputUsdValue);
192
205
 
193
206
  const completeModalDesc =
@@ -280,7 +293,7 @@ export function SwapDetails(props: SwapDetailsProps) {
280
293
  </div>
281
294
  <div className={rowStyles()}>
282
295
  <Typography variant="label" size="large" color="neutral700">
283
- {`${i18n.t('Created at')}:`}
296
+ {`${i18n.t(swap.finishTime ? 'Finished at' : 'Created at')}:`}
284
297
  </Typography>
285
298
  <Typography variant="label" size="small" color="neutral700">
286
299
  {swapDate}
@@ -307,6 +320,8 @@ export function SwapDetails(props: SwapDetailsProps) {
307
320
  TOKEN_AMOUNT_MAX_DECIMALS
308
321
  ),
309
322
  usdValue: inputUsdValue,
323
+ realUsdValue: realInputUsdValue,
324
+ realValue: swap.inputAmount,
310
325
  },
311
326
  token: {
312
327
  displayName: steps[0].from.token.displayName,
@@ -325,6 +340,8 @@ export function SwapDetails(props: SwapDetailsProps) {
325
340
  TOKEN_AMOUNT_MAX_DECIMALS
326
341
  ),
327
342
  usdValue: outputUsdValue,
343
+ realUsdValue: realOutputUsdValue,
344
+ realValue: outputAmount,
328
345
  },
329
346
  token: {
330
347
  displayName: steps[numberOfSteps - 1].to.token.displayName,
@@ -368,6 +385,7 @@ export function SwapDetails(props: SwapDetailsProps) {
368
385
  hasSeparator={index !== 0}
369
386
  tabIndex={key}
370
387
  isFocused={isFocused}
388
+ tooltipContainer={getContainer()}
371
389
  />
372
390
  );
373
391
  })}
@@ -393,6 +411,8 @@ export function SwapDetails(props: SwapDetailsProps) {
393
411
  TOKEN_AMOUNT_MAX_DECIMALS
394
412
  )}
395
413
  usdValue={outputUsdValue}
414
+ realUsdValue={realOutputUsdValue}
415
+ realValue={formatTooltipNumbers(outputAmount)}
396
416
  percentageChange={numberToString(
397
417
  percentageChange,
398
418
  PERCENTAGE_CHANGE_MIN_DECIMALS,
@@ -13,6 +13,7 @@ import React from 'react';
13
13
  import { useNavigate } from 'react-router-dom';
14
14
 
15
15
  import { RANGO_SWAP_BOX_ID } from '../../constants';
16
+ import { getContainer } from '../../utils/common';
16
17
 
17
18
  export function SwapDetailsCompleteModal(props: CompleteModalPropTypes) {
18
19
  const {
@@ -21,6 +22,8 @@ export function SwapDetailsCompleteModal(props: CompleteModalPropTypes) {
21
22
  status,
22
23
  priceValue,
23
24
  usdValue,
25
+ realUsdValue,
26
+ realValue,
24
27
  token,
25
28
  chain,
26
29
  percentageChange,
@@ -38,11 +41,14 @@ export function SwapDetailsCompleteModal(props: CompleteModalPropTypes) {
38
41
  <MessageBox type="success" title={i18n.t('Swap Successful')}>
39
42
  <TokenAmount
40
43
  direction="vertical"
44
+ tooltipContainer={getContainer()}
41
45
  type="output"
42
46
  centerAlign={true}
43
47
  price={{
44
48
  value: priceValue,
45
49
  usdValue,
50
+ realUsdValue,
51
+ realValue,
46
52
  }}
47
53
  token={token}
48
54
  chain={chain}
@@ -24,7 +24,9 @@ export interface CompleteModalPropTypes {
24
24
  onClose: () => void;
25
25
  status: 'success' | 'failed';
26
26
  priceValue: string;
27
+ realValue: string;
27
28
  usdValue: string;
29
+ realUsdValue: string;
28
30
  percentageChange: string;
29
31
  chain: {
30
32
  displayName?: string;
@@ -4,7 +4,12 @@ import { i18n } from '@lingui/core';
4
4
  import { Divider, SwapListItem, Typography } from '@rango-dev/ui';
5
5
  import React from 'react';
6
6
 
7
- import { limitDecimalPlaces } from '../../utils/numbers';
7
+ import {
8
+ TOKEN_AMOUNT_MAX_DECIMALS,
9
+ TOKEN_AMOUNT_MIN_DECIMALS,
10
+ } from '../../constants/routing';
11
+ import { getContainer } from '../../utils/common';
12
+ import { formatTooltipNumbers, numberToString } from '../../utils/numbers';
8
13
 
9
14
  import { Group, groupStyles, SwapList, Time } from './SwapsGroup.styles';
10
15
 
@@ -17,11 +22,11 @@ export function SwapsGroup(props: PropTypes) {
17
22
 
18
23
  const loadingGroups = [
19
24
  {
20
- title: 'Today',
25
+ title: i18n.t('Today'),
21
26
  swaps,
22
27
  },
23
28
  {
24
- title: 'Last month',
29
+ title: i18n.t('This month'),
25
30
  swaps,
26
31
  },
27
32
  ];
@@ -35,7 +40,7 @@ export function SwapsGroup(props: PropTypes) {
35
40
  variant="label"
36
41
  size="medium"
37
42
  className={groupStyles()}>
38
- {i18n.t(group.title)}
43
+ {group.title}
39
44
  </Typography>
40
45
  </Time>
41
46
  <Divider size={4} />
@@ -68,13 +73,14 @@ export function SwapsGroup(props: PropTypes) {
68
73
  variant="label"
69
74
  size="medium"
70
75
  className={groupStyles()}>
71
- {i18n.t(group.title)}
76
+ {group.title}
72
77
  </Typography>
73
78
  </Time>
74
79
  <Divider size={4} />
75
80
  <SwapList>
76
81
  {group.swaps.map((swap) => {
77
82
  const firstStep = swap.steps[0];
83
+
78
84
  const lastStep = swap.steps[swap.steps.length - 1];
79
85
  return (
80
86
  <React.Fragment key={swap.requestId}>
@@ -83,7 +89,8 @@ export function SwapsGroup(props: PropTypes) {
83
89
  creationTime={swap.creationTime}
84
90
  status={swap.status}
85
91
  onClick={onSwapClick}
86
- onlyShowTime={group.title === 'Today'}
92
+ tooltipContainer={getContainer()}
93
+ onlyShowTime={group.title === i18n.t('Today')}
87
94
  swapTokenData={{
88
95
  from: {
89
96
  token: {
@@ -93,7 +100,12 @@ export function SwapsGroup(props: PropTypes) {
93
100
  blockchain: {
94
101
  image: firstStep.fromBlockchainLogo || '',
95
102
  },
96
- amount: limitDecimalPlaces(swap.inputAmount),
103
+ amount: numberToString(
104
+ swap.inputAmount,
105
+ TOKEN_AMOUNT_MIN_DECIMALS,
106
+ TOKEN_AMOUNT_MAX_DECIMALS
107
+ ),
108
+ realAmount: formatTooltipNumbers(swap.inputAmount),
97
109
  },
98
110
  to: {
99
111
  token: {
@@ -103,11 +115,16 @@ export function SwapsGroup(props: PropTypes) {
103
115
  blockchain: {
104
116
  image: lastStep.toBlockchainLogo || '',
105
117
  },
106
- amount: limitDecimalPlaces(
107
- lastStep.outputAmount || ''
118
+ amount: numberToString(
119
+ lastStep.outputAmount ||
120
+ lastStep.expectedOutputAmountHumanReadable ||
121
+ '',
122
+ TOKEN_AMOUNT_MIN_DECIMALS,
123
+ TOKEN_AMOUNT_MAX_DECIMALS
108
124
  ),
109
- estimatedAmount: limitDecimalPlaces(
110
- lastStep.expectedOutputAmountHumanReadable || ''
125
+ realAmount: formatTooltipNumbers(
126
+ lastStep.outputAmount ||
127
+ lastStep.expectedOutputAmountHumanReadable
111
128
  ),
112
129
  },
113
130
  }}
@@ -15,3 +15,5 @@ export const PERCENTAGE_CHANGE_MAX_DECIMALS = 2;
15
15
 
16
16
  export const BALANCE_MIN_DECIMALS = 8;
17
17
  export const BALANCE_MAX_DECIMALS = 8;
18
+
19
+ export const TOOLTIP_DECIMALS = 12;
@@ -3,6 +3,7 @@ import type {
3
3
  PropTypes,
4
4
  WidgetContextInterface,
5
5
  } from './Wallets.types';
6
+ import type { Wallet } from '../../types/wallets';
6
7
  import type { ProvidersOptions } from '../../utils/providers';
7
8
  import type { EventHandler } from '@rango-dev/wallets-react';
8
9
  import type { Network } from '@rango-dev/wallets-shared';
@@ -10,7 +11,7 @@ import type { PropsWithChildren } from 'react';
10
11
 
11
12
  import { Events, Provider } from '@rango-dev/wallets-react';
12
13
  import { isEvmBlockchain } from 'rango-sdk';
13
- import React, { createContext, useEffect, useRef } from 'react';
14
+ import React, { createContext, useEffect, useRef, useState } from 'react';
14
15
 
15
16
  import { useSyncStoresWithConfig } from '../../hooks/useSyncStoresWithConfig';
16
17
  import { useWalletProviders } from '../../hooks/useWalletProviders';
@@ -34,6 +35,7 @@ function Main(props: PropsWithChildren<PropTypes>) {
34
35
  const walletOptions: ProvidersOptions = {
35
36
  walletConnectProjectId: props.config?.walletConnectProjectId,
36
37
  };
38
+ const [accounts, setAccounts] = useState<Wallet[]>([]);
37
39
  const { providers } = useWalletProviders(props.config.wallets, walletOptions);
38
40
  const { connectWallet, disconnectWallet } = useWalletsStore();
39
41
  const onConnectWalletHandler = useRef<OnConnectHandler>();
@@ -66,7 +68,7 @@ function Main(props: PropsWithChildren<PropTypes>) {
66
68
  supportedChainNames,
67
69
  meta.isContractWallet
68
70
  );
69
- connectWallet(data, tokens);
71
+ setAccounts(data);
70
72
  } else {
71
73
  disconnectWallet(type);
72
74
  }
@@ -99,6 +101,13 @@ function Main(props: PropsWithChildren<PropTypes>) {
99
101
  props.onUpdateState(type, event, value, state, meta);
100
102
  }
101
103
  };
104
+
105
+ useEffect(() => {
106
+ if (accounts.length) {
107
+ connectWallet(accounts, tokens);
108
+ }
109
+ }, [accounts, tokens]);
110
+
102
111
  return (
103
112
  <WidgetContext.Provider
104
113
  // eslint-disable-next-line react/jsx-no-constructed-context-values
@@ -48,6 +48,7 @@ export function useSwapInput(): UseSwapInput {
48
48
  toToken,
49
49
  inputAmount,
50
50
  inputUsdValue,
51
+ quote,
51
52
  resetQuote,
52
53
  setQuote,
53
54
  } = useQuoteStore();
@@ -63,9 +64,9 @@ export function useSwapInput(): UseSwapInput {
63
64
  const [error, setError] = useState<QuoteError | null>(null);
64
65
  const [warning, setWarning] = useState<QuoteWarning | null>(null);
65
66
  const userSlippage = customSlippage ?? slippage;
66
- const hasTokensValue = !fromToken || !toToken;
67
+ const tokensValueInvalid = !fromToken || !toToken;
67
68
  const shouldSkipRequest =
68
- hasTokensValue ||
69
+ tokensValueInvalid ||
69
70
  tokensAreEqual(fromToken, toToken) ||
70
71
  !isPositiveNumber(inputAmount);
71
72
 
@@ -153,6 +154,9 @@ export function useSwapInput(): UseSwapInput {
153
154
  return;
154
155
  }
155
156
  if (shouldSkipRequest) {
157
+ if (quote) {
158
+ resetQuote();
159
+ }
156
160
  return;
157
161
  }
158
162
  resetQuote();
@@ -1,9 +1,13 @@
1
1
  import type { Asset } from 'rango-sdk';
2
2
 
3
- import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
3
+ import { useEffect, useLayoutEffect, useRef } from 'react';
4
4
 
5
5
  import { useAppStore } from '../store/AppStore';
6
6
  import { useQuoteStore } from '../store/quote';
7
+ import {
8
+ isBlockchainExcludedInConfig,
9
+ isTokenExcludedInConfig,
10
+ } from '../utils/configs';
7
11
  import { tokensAreEqual } from '../utils/wallets';
8
12
 
9
13
  export function useSyncStoresWithConfig() {
@@ -27,22 +31,10 @@ export function useSyncStoresWithConfig() {
27
31
  const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } =
28
32
  useAppStore();
29
33
 
30
- const fromTokensConfig = useMemo(
31
- () => config?.from?.tokens,
32
- [config?.from?.tokens]
33
- );
34
- const fromBlockchainsConfig = useMemo(
35
- () => config?.from?.blockchains,
36
- [config?.from?.blockchains]
37
- );
38
- const toTokensConfig = useMemo(
39
- () => config?.to?.tokens,
40
- [config?.to?.tokens]
41
- );
42
- const toBlockchainsConfig = useMemo(
43
- () => config?.to?.blockchains,
44
- [config?.to?.blockchains]
45
- );
34
+ const fromTokensConfig = config?.from?.tokens;
35
+ const fromBlockchainsConfig = config?.from?.blockchains;
36
+ const toTokensConfig = config?.to?.tokens;
37
+ const toBlockchainsConfig = config?.to?.blockchains;
46
38
  const prevConfigFromToken = useRef<Asset | undefined>(undefined);
47
39
  const prevConfigToToken = useRef<Asset | undefined>(undefined);
48
40
  const prevConfigFromBlockchain = useRef<string | undefined>(undefined);
@@ -90,30 +82,21 @@ export function useSyncStoresWithConfig() {
90
82
  ]);
91
83
 
92
84
  useEffect(() => {
93
- if (fromToken && fromTokensConfig) {
94
- if (!fromTokensConfig.some((token) => tokensAreEqual(token, fromToken))) {
95
- setFromToken({ token: null });
96
- }
85
+ if (isTokenExcludedInConfig(fromToken, fromTokensConfig)) {
86
+ setFromToken({ token: null });
97
87
  }
98
88
 
99
- if (fromBlockchain && fromBlockchainsConfig) {
100
- if (!fromBlockchainsConfig.includes(fromBlockchain.name)) {
101
- setFromBlockchain(null);
102
- }
89
+ if (isBlockchainExcludedInConfig(fromBlockchain, fromBlockchainsConfig)) {
90
+ setFromBlockchain(null);
103
91
  }
104
92
  }, [fromTokensConfig, fromBlockchainsConfig]);
105
93
 
106
94
  useEffect(() => {
107
- if (toToken && toTokensConfig) {
108
- if (!toTokensConfig.some((token) => tokensAreEqual(token, toToken))) {
109
- setToToken({ token: null });
110
- }
95
+ if (isTokenExcludedInConfig(toToken, toTokensConfig)) {
96
+ setFromToken({ token: null });
111
97
  }
112
-
113
- if (toBlockchain && toBlockchainsConfig) {
114
- if (!toBlockchainsConfig.includes(toBlockchain.name)) {
115
- setToBlockchain(null);
116
- }
98
+ if (isBlockchainExcludedInConfig(toBlockchain, toBlockchainsConfig)) {
99
+ setToBlockchain(null);
117
100
  }
118
101
  }, [toTokensConfig, toBlockchainsConfig]);
119
102
 
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import type { WidgetProps } from './containers/Widget';
2
2
  import type { ConnectedWallet } from './store/wallets';
3
3
  import type {
4
4
  BlockchainAndTokenConfig,
5
+ Tokens,
5
6
  WidgetColors,
6
7
  WidgetColorsKeys,
7
8
  WidgetConfig,
@@ -86,6 +87,7 @@ export type {
86
87
  StepOutputRevealedEvent,
87
88
  HandleWalletsUpdate,
88
89
  ConnectedWallet,
90
+ Tokens,
89
91
  };
90
92
  export {
91
93
  Widget,
@@ -12,7 +12,6 @@ import {
12
12
  css,
13
13
  Divider,
14
14
  IconButton,
15
- RefreshIcon,
16
15
  SettingsIcon,
17
16
  styled,
18
17
  Tooltip,
@@ -26,6 +25,7 @@ import { useNavigate } from 'react-router-dom';
26
25
  import { getRequiredWallets } from '../components/ConfirmWalletsModal/ConfirmWallets.helpers';
27
26
  import { ConfirmWalletsModal } from '../components/ConfirmWalletsModal/ConfirmWalletsModal';
28
27
  import { HeaderButton } from '../components/HeaderButtons/HeaderButtons.styles';
28
+ import { RefreshButton } from '../components/HeaderButtons/RefreshButton';
29
29
  import { Layout } from '../components/Layout';
30
30
  import { navigationRoutes } from '../constants/navigationRoutes';
31
31
  import { getQuoteUpdateWarningMessage } from '../constants/warnings';
@@ -324,15 +324,17 @@ export function ConfirmSwapPage() {
324
324
  <Typography variant="title" size="small">
325
325
  {i18n.t('You get')}
326
326
  </Typography>
327
- <Button
328
- style={{ padding: '0' }}
329
- variant="ghost"
330
- disabled={fetchingConfirmationQuote}
331
- onClick={onRefresh}>
332
- <div className={iconStyles()}>
333
- <RefreshIcon size={16} />
334
- </div>
335
- </Button>
327
+ <div className={iconStyles()}>
328
+ <RefreshButton
329
+ onClick={
330
+ !fetchingConfirmationQuote &&
331
+ !showWallets &&
332
+ !showQuoteWarningModal
333
+ ? onRefresh
334
+ : undefined
335
+ }
336
+ />
337
+ </div>
336
338
  </div>
337
339
  {dbErrorMessage && (
338
340
  <>
@@ -22,7 +22,8 @@ import { useAppStore } from '../store/AppStore';
22
22
  import { useQuoteStore } from '../store/quote';
23
23
  import { useUiStore } from '../store/ui';
24
24
  import { useWalletsStore } from '../store/wallets';
25
- import { numberToString } from '../utils/numbers';
25
+ import { getContainer } from '../utils/common';
26
+ import { formatTooltipNumbers, numberToString } from '../utils/numbers';
26
27
  import { getPriceImpact, getPriceImpactLevel } from '../utils/quote';
27
28
  import { canComputePriceImpact, getSwapButtonState } from '../utils/swap';
28
29
  import { formatBalance, isFetchingBalance } from '../utils/wallets';
@@ -160,7 +161,11 @@ export function Home() {
160
161
  suffix: (
161
162
  <HomeButtons
162
163
  layoutRef={layoutRef.current}
163
- onClickRefresh={!!quote || quoteError ? fetchQuote : undefined}
164
+ onClickRefresh={
165
+ (!!quote || quoteError) && !showQuoteWarningModal
166
+ ? fetchQuote
167
+ : undefined
168
+ }
164
169
  onClickHistory={() => navigate(navigationRoutes.swaps)}
165
170
  onClickSettings={() => navigate(navigationRoutes.settings)}
166
171
  />
@@ -192,6 +197,9 @@ export function Home() {
192
197
  USD_VALUE_MIN_DECIMALS,
193
198
  USD_VALUE_MAX_DECIMALS
194
199
  ),
200
+ realUsdValue: priceImpactInputCanNotBeComputed
201
+ ? undefined
202
+ : formatTooltipNumbers(inputUsdValue),
195
203
  error: priceImpactInputCanNotBeComputed
196
204
  ? errorMessages().unknownPriceError.impactTitle
197
205
  : undefined,
@@ -199,6 +207,7 @@ export function Home() {
199
207
  disabled={fetchMetaStatus === 'failed'}
200
208
  loading={fetchMetaStatus === 'loading'}
201
209
  loadingBalance={fetchingBalance}
210
+ tooltipContainer={getContainer()}
202
211
  onSelectMaxBalance={() => {
203
212
  if (fromTokenFormattedBalance !== '0') {
204
213
  setInputAmount(tokenBalanceReal.split(',').join(''));
@@ -239,6 +248,10 @@ export function Home() {
239
248
  USD_VALUE_MIN_DECIMALS,
240
249
  USD_VALUE_MAX_DECIMALS
241
250
  ),
251
+ realValue: formatTooltipNumbers(outputAmount),
252
+ realUsdValue: priceImpactOutputCanNotBeComputed
253
+ ? undefined
254
+ : formatTooltipNumbers(outputUsdValue),
242
255
  error: priceImpactOutputCanNotBeComputed
243
256
  ? errorMessages().unknownPriceError.impactTitle
244
257
  : undefined,
@@ -246,6 +259,7 @@ export function Home() {
246
259
  onClickToken={() => navigate(navigationRoutes.toSwap)}
247
260
  disabled={fetchMetaStatus === 'failed'}
248
261
  loading={fetchMetaStatus === 'loading'}
262
+ tooltipContainer={getContainer()}
249
263
  />
250
264
  </InputsContainer>
251
265
  <div className="quote__container">
@@ -40,6 +40,7 @@ export function LiquiditySourcePage({ sourceType }: PropTypes) {
40
40
  const supportedUniqueSwappersGroups: Array<UniqueSwappersGroupType> =
41
41
  getUniqueSwappersGroups(swappers, disabledLiquiditySources);
42
42
 
43
+ const types = { Exchanges: i18n.t('Exchanges'), Bridges: i18n.t('Bridges') };
43
44
  const validTypes: Array<LiquiditySourceType> = [];
44
45
  if (sourceType === 'Exchanges') {
45
46
  validTypes.push('DEX');
@@ -103,7 +104,7 @@ export function LiquiditySourcePage({ sourceType }: PropTypes) {
103
104
  suffix: (
104
105
  <LiquiditySourceSuffix>
105
106
  <Button variant="ghost" size="xsmall" onClick={toggleAllSources}>
106
- {i18n.t(hasSelectAll ? 'Deselect all' : 'Select all')}
107
+ {hasSelectAll ? i18n.t('Deselect all') : i18n.t('Select all')}
107
108
  </Button>
108
109
  </LiquiditySourceSuffix>
109
110
  ),
@@ -115,7 +116,9 @@ export function LiquiditySourcePage({ sourceType }: PropTypes) {
115
116
  fullWidth
116
117
  color="light"
117
118
  variant="contained"
118
- placeholder={i18n.t('Search {sourceType}', { sourceType })}
119
+ placeholder={i18n.t('Search {sourceType}', {
120
+ sourceType: types[sourceType],
121
+ })}
119
122
  onChange={searchHandler}
120
123
  />
121
124
  {fetchStatus === 'loading' && <LoadingLiquiditySourceList />}
@@ -2,7 +2,7 @@ import { i18n } from '@lingui/core';
2
2
  import {
3
3
  Divider,
4
4
  getCountCategories,
5
- SelectableCategoryList
5
+ SelectableCategoryList,
6
6
  } from '@rango-dev/ui';
7
7
  import React, { useState } from 'react';
8
8
 
@@ -27,7 +27,7 @@ export function SelectBlockchainPage(props: PropTypes) {
27
27
  const fetchStatus = useAppStore().fetchStatus;
28
28
 
29
29
  const blockchains = useAppStore().blockchains({
30
- type: type
30
+ type,
31
31
  });
32
32
 
33
33
  const countActiveCategories = getCountCategories(blockchains);
@@ -37,7 +37,7 @@ export function SelectBlockchainPage(props: PropTypes) {
37
37
  return (
38
38
  <Layout
39
39
  header={{
40
- title: i18n.t(`Select Blockchain`)
40
+ title: i18n.t(`Select Blockchain`),
41
41
  }}>
42
42
  <Divider size={12} />
43
43
 
@@ -68,11 +68,15 @@ export function SelectSwapItemsPage(props: PropTypes) {
68
68
  setToToken({ token, meta: { blockchains, tokens } });
69
69
  }
70
70
  };
71
+ const types = {
72
+ source: i18n.t('Source'),
73
+ destination: i18n.t('Destination'),
74
+ };
71
75
 
72
76
  return (
73
77
  <Layout
74
78
  header={{
75
- title: i18n.t('Swap {type}', { type }),
79
+ title: i18n.t('Swap {type}', { type: types[type] }),
76
80
  }}>
77
81
  <BlockchainsSection
78
82
  blockchains={blockchains}
@@ -6,6 +6,7 @@ import type { StateCreator } from 'zustand';
6
6
 
7
7
  import { httpService as sdk } from '../../services/httpService';
8
8
  import { containsText } from '../../utils/common';
9
+ import { isTokenExcludedInConfig } from '../../utils/configs';
9
10
  import { sortLiquiditySourcesByGroupTitle } from '../../utils/settings';
10
11
  import { tokensAreEqual } from '../../utils/wallets';
11
12
 
@@ -81,21 +82,18 @@ export const createDataSlice: StateCreator<
81
82
  }
82
83
 
83
84
  const config = get().config;
84
- const supportedTokensFromConfig =
85
+ const supportedTokensConfig =
85
86
  (options.type === 'source' ? config.from?.tokens : config.to?.tokens) ??
86
- [];
87
+ {};
87
88
  const blockchains = get().blockchains({
88
89
  type: options.type,
89
90
  });
90
91
 
91
92
  const list = tokensFromState
92
93
  .filter((token) => {
93
- // If there is a list of tokens in config, we only keep them.
94
94
  if (
95
- supportedTokensFromConfig.length > 0 &&
96
- !supportedTokensFromConfig.some((asset) => {
97
- return tokensAreEqual(asset, token);
98
- })
95
+ supportedTokensConfig &&
96
+ isTokenExcludedInConfig(token, supportedTokensConfig)
99
97
  ) {
100
98
  return false;
101
99
  }
@@ -67,6 +67,19 @@ export type WidgetAffiliate = {
67
67
  wallets?: { [key: string]: string };
68
68
  };
69
69
 
70
+ /**
71
+ * `Tokens`
72
+ *
73
+ * @property {boolean} isExcluded - This is a boolean property capable of removing tokens from all or a blockchain.
74
+ * @property {Asset[]} tokens - The `tokens` property is an array of `Asset` objects that
75
+ * you could use that to limit tokens to some limited ones.
76
+ */
77
+
78
+ export type Tokens = {
79
+ isExcluded: boolean;
80
+ tokens: Asset[];
81
+ };
82
+
70
83
  /**
71
84
  * `BlockchainAndTokenConfig`
72
85
  *
@@ -75,8 +88,8 @@ export type WidgetAffiliate = {
75
88
  * which is selected. e.g. {blockchain: 'BSC', symbol: 'BNB', address: null}
76
89
  * @property {string[]} blockchains - An optional array of strings representing the supported
77
90
  * blockchains. e.g. ['BSC','ETHEREUM']
78
- * @property {Asset[]} tokens - The `tokens` property is an optional array of `Asset` objects that
79
- * you could use that to limit tokens to some limited ones.
91
+ * @property {Asset[] |{ [blockchain: string]: Tokens }} tokens - The `tokens` property is an optional object of `blockchain` objects or array of `Asset` objects
92
+ * that you could use that to limit tokens to some limited ones.
80
93
  * @property {Asset} pinnedTokens - The `pinnedTokens` property is an optional array of `Asset` objects that
81
94
  * you could use to pin tokens of your choice to the top of the token list.
82
95
  */
@@ -84,8 +97,8 @@ export type BlockchainAndTokenConfig = {
84
97
  blockchain?: string;
85
98
  token?: Asset;
86
99
  blockchains?: string[];
87
- tokens?: Asset[];
88
100
  pinnedTokens?: Asset[];
101
+ tokens?: Asset[] | { [blockchain: string]: Tokens };
89
102
  };
90
103
 
91
104
  /**