@rango-dev/widget-embedded 0.42.3 → 0.42.4-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +2 -5
  3. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  4. package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
  5. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  6. package/dist/components/NoResult/NoResult.types.d.ts +1 -0
  7. package/dist/components/NoResult/NoResult.types.d.ts.map +1 -1
  8. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.d.ts.map +1 -1
  9. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts +5 -3
  10. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts.map +1 -1
  11. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts +440 -0
  12. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
  13. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts +2 -0
  14. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts.map +1 -1
  15. package/dist/components/QuoteWarningsAndErrors/SlippageWariningModal.d.ts.map +1 -1
  16. package/dist/components/Slippage/Slippage.d.ts.map +1 -1
  17. package/dist/components/Slippage/Slippage.styles.d.ts +162 -0
  18. package/dist/components/Slippage/Slippage.styles.d.ts.map +1 -1
  19. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.d.ts +4 -0
  20. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.d.ts.map +1 -0
  21. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.d.ts +8 -0
  22. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.d.ts.map +1 -0
  23. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.d.ts +4 -0
  24. package/dist/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.d.ts.map +1 -0
  25. package/dist/components/StatefulConnectModal/StatefulConnectModal.d.ts.map +1 -1
  26. package/dist/components/StatefulConnectModal/helpers.d.ts +3 -0
  27. package/dist/components/StatefulConnectModal/helpers.d.ts.map +1 -1
  28. package/dist/components/StatefulConnectModal/index.d.ts +1 -1
  29. package/dist/components/StatefulConnectModal/index.d.ts.map +1 -1
  30. package/dist/components/SwapMetrics/SwapMetrics.constants.d.ts +5 -0
  31. package/dist/components/SwapMetrics/SwapMetrics.constants.d.ts.map +1 -0
  32. package/dist/components/SwapMetrics/SwapMetrics.d.ts +4 -0
  33. package/dist/components/SwapMetrics/SwapMetrics.d.ts.map +1 -0
  34. package/dist/components/SwapMetrics/SwapMetrics.helpers.d.ts +11 -0
  35. package/dist/components/SwapMetrics/SwapMetrics.helpers.d.ts.map +1 -0
  36. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts +482 -0
  37. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts.map +1 -0
  38. package/dist/components/SwapMetrics/SwapMetrics.types.d.ts +27 -0
  39. package/dist/components/SwapMetrics/SwapMetrics.types.d.ts.map +1 -0
  40. package/dist/components/SwapMetrics/index.d.ts +2 -0
  41. package/dist/components/SwapMetrics/index.d.ts.map +1 -0
  42. package/dist/components/WalletStatefulConnect/Detached.d.ts +4 -0
  43. package/dist/components/WalletStatefulConnect/Detached.d.ts.map +1 -0
  44. package/dist/components/WalletStatefulConnect/Detached.types.d.ts +8 -0
  45. package/dist/components/WalletStatefulConnect/Detached.types.d.ts.map +1 -0
  46. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts +4 -0
  47. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts.map +1 -0
  48. package/dist/components/WalletStatefulConnect/NamespaceListItem.d.ts.map +1 -1
  49. package/dist/components/WalletStatefulConnect/NamespaceUnsupportedItem.d.ts +4 -0
  50. package/dist/components/WalletStatefulConnect/NamespaceUnsupportedItem.d.ts.map +1 -0
  51. package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
  52. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts +805 -3
  53. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts.map +1 -1
  54. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts +11 -8
  55. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts.map +1 -1
  56. package/dist/components/WalletStatefulConnect/index.d.ts +1 -0
  57. package/dist/components/WalletStatefulConnect/index.d.ts.map +1 -1
  58. package/dist/constants/errors.d.ts.map +1 -1
  59. package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
  60. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  61. package/dist/containers/Wallets/Wallets.types.d.ts +5 -3
  62. package/dist/containers/Wallets/Wallets.types.d.ts.map +1 -1
  63. package/dist/containers/Wallets/useUpdates.d.ts +3 -3
  64. package/dist/containers/Wallets/useUpdates.d.ts.map +1 -1
  65. package/dist/hooks/useBootstrap/useBootstrap.d.ts.map +1 -1
  66. package/dist/hooks/useConfirmSwap/useConfirmSwap.helpers.d.ts.map +1 -1
  67. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
  68. package/dist/hooks/useStatefulConnect/useStatefulConnect.state.d.ts +3 -1
  69. package/dist/hooks/useStatefulConnect/useStatefulConnect.state.d.ts.map +1 -1
  70. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts +11 -2
  71. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts.map +1 -1
  72. package/dist/hooks/useSyncUrlAndStore/useSyncUrlAndStore.d.ts.map +1 -1
  73. package/dist/hooks/useWalletList.d.ts +2 -2
  74. package/dist/hooks/useWalletList.d.ts.map +1 -1
  75. package/dist/index.d.ts +4 -2
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +2 -2
  78. package/dist/index.js.map +4 -4
  79. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  80. package/dist/pages/Home.d.ts.map +1 -1
  81. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  82. package/dist/pages/WalletsPage.d.ts.map +1 -1
  83. package/dist/store/AppStore.d.ts +2 -0
  84. package/dist/store/AppStore.d.ts.map +1 -1
  85. package/dist/store/app.d.ts +2 -0
  86. package/dist/store/app.d.ts.map +1 -1
  87. package/dist/store/quote.d.ts +2 -0
  88. package/dist/store/quote.d.ts.map +1 -1
  89. package/dist/store/slices/settings.d.ts +3 -0
  90. package/dist/store/slices/settings.d.ts.map +1 -1
  91. package/dist/types/quote.d.ts +1 -0
  92. package/dist/types/quote.d.ts.map +1 -1
  93. package/dist/utils/colors.d.ts.map +1 -1
  94. package/dist/utils/numbers.d.ts +1 -0
  95. package/dist/utils/numbers.d.ts.map +1 -1
  96. package/dist/utils/sanitizers.d.ts +27 -0
  97. package/dist/utils/sanitizers.d.ts.map +1 -0
  98. package/dist/utils/sanitizers.test.d.ts +2 -0
  99. package/dist/utils/sanitizers.test.d.ts.map +1 -0
  100. package/dist/utils/settings.d.ts +2 -1
  101. package/dist/utils/settings.d.ts.map +1 -1
  102. package/dist/utils/validation.d.ts +26 -0
  103. package/dist/utils/validation.d.ts.map +1 -0
  104. package/dist/utils/validation.test.d.ts +2 -0
  105. package/dist/utils/validation.test.d.ts.map +1 -0
  106. package/dist/utils/wallets.d.ts +9 -1
  107. package/dist/utils/wallets.d.ts.map +1 -1
  108. package/dist/widget-embedded.build.json +1 -1
  109. package/package.json +9 -9
  110. package/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts +4 -47
  111. package/src/components/ConfirmWalletsModal/WalletList.tsx +35 -19
  112. package/src/components/NoResult/NoResult.tsx +4 -1
  113. package/src/components/NoResult/NoResult.types.ts +1 -0
  114. package/src/components/Quote/Quote.tsx +1 -1
  115. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts +29 -4
  116. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts +10 -1
  117. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx +38 -7
  118. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts +2 -0
  119. package/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx +20 -21
  120. package/src/components/Slippage/Slippage.styles.ts +23 -0
  121. package/src/components/Slippage/Slippage.tsx +28 -22
  122. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.helpers.ts +33 -0
  123. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.tsx +48 -0
  124. package/src/components/SlippageWarningsAndErrors/SlippageWarningsAndErrors.types.ts +3 -0
  125. package/src/components/StatefulConnectModal/StatefulConnectModal.tsx +19 -1
  126. package/src/components/StatefulConnectModal/helpers.ts +6 -0
  127. package/src/components/StatefulConnectModal/index.ts +1 -1
  128. package/src/components/SwapMetrics/SwapMetrics.constants.ts +4 -0
  129. package/src/components/SwapMetrics/SwapMetrics.helpers.ts +76 -0
  130. package/src/components/SwapMetrics/SwapMetrics.styles.ts +32 -0
  131. package/src/components/SwapMetrics/SwapMetrics.tsx +134 -0
  132. package/src/components/SwapMetrics/SwapMetrics.types.ts +26 -0
  133. package/src/components/SwapMetrics/index.ts +1 -0
  134. package/src/components/WalletStatefulConnect/Detached.tsx +53 -0
  135. package/src/components/WalletStatefulConnect/Detached.types.ts +8 -0
  136. package/src/components/WalletStatefulConnect/NamespaceDetachedItem.tsx +177 -0
  137. package/src/components/WalletStatefulConnect/NamespaceListItem.tsx +14 -33
  138. package/src/components/WalletStatefulConnect/NamespaceUnsupportedItem.tsx +42 -0
  139. package/src/components/WalletStatefulConnect/Namespaces.styles.ts +44 -6
  140. package/src/components/WalletStatefulConnect/Namespaces.tsx +12 -7
  141. package/src/components/WalletStatefulConnect/Namespaces.types.tsx +13 -11
  142. package/src/components/WalletStatefulConnect/index.ts +1 -0
  143. package/src/constants/errors.ts +6 -7
  144. package/src/containers/Inputs/Inputs.tsx +2 -0
  145. package/src/containers/Wallets/Wallets.tsx +6 -5
  146. package/src/containers/Wallets/Wallets.types.ts +5 -3
  147. package/src/containers/Wallets/useUpdates.ts +40 -32
  148. package/src/hooks/useBootstrap/useBootstrap.ts +33 -10
  149. package/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts +1 -0
  150. package/src/hooks/useConfirmSwap/useConfirmSwap.ts +1 -1
  151. package/src/hooks/useStatefulConnect/useStatefulConnect.state.ts +11 -1
  152. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +33 -4
  153. package/src/hooks/useStatefulConnect/useStatefulConnect.types.ts +13 -1
  154. package/src/hooks/useSwapInput.ts +1 -1
  155. package/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts +2 -0
  156. package/src/hooks/useWalletList.ts +3 -3
  157. package/src/index.ts +8 -1
  158. package/src/pages/ConfirmSwapPage.tsx +6 -1
  159. package/src/pages/Home.tsx +61 -12
  160. package/src/pages/LiquiditySourcePage.tsx +5 -3
  161. package/src/pages/WalletsPage.tsx +17 -1
  162. package/src/store/app.ts +1 -0
  163. package/src/store/quote.ts +23 -4
  164. package/src/store/slices/settings.ts +11 -0
  165. package/src/types/quote.ts +4 -1
  166. package/src/utils/colors.ts +3 -10
  167. package/src/utils/numbers.ts +11 -0
  168. package/src/utils/sanitizers.test.ts +122 -0
  169. package/src/utils/sanitizers.ts +41 -0
  170. package/src/utils/settings.ts +11 -4
  171. package/src/utils/validation.test.ts +121 -0
  172. package/src/utils/validation.ts +45 -0
  173. package/src/utils/wallets.ts +59 -14
@@ -0,0 +1,48 @@
1
+ import type { ActionType } from './SlippageWarningsAndErrors.helpers';
2
+ import type { PropTypes } from './SlippageWarningsAndErrors.types';
3
+
4
+ import { Alert, Button } from '@rango-dev/ui';
5
+ import React from 'react';
6
+
7
+ import { DEFAULT_SLIPPAGE } from '../../constants/swapSettings';
8
+ import { useAppStore } from '../../store/AppStore';
9
+
10
+ import { makeAlerts } from './SlippageWarningsAndErrors.helpers';
11
+
12
+ export function SlippageWarningsAndErrors(props: PropTypes) {
13
+ const { slippage, customSlippage, setSlippage, setCustomSlippage } =
14
+ useAppStore();
15
+ const { onChangeSettings } = props;
16
+ const currentSlippage = customSlippage !== null ? customSlippage : slippage;
17
+
18
+ const alertInfo = makeAlerts(currentSlippage);
19
+
20
+ const onClickActionButton = (action: ActionType) => {
21
+ if (action === 'reset-slippage') {
22
+ setSlippage(DEFAULT_SLIPPAGE);
23
+ setCustomSlippage(null);
24
+ } else if (action === 'change-settings') {
25
+ onChangeSettings();
26
+ }
27
+ };
28
+
29
+ if (!alertInfo) {
30
+ return null;
31
+ }
32
+ return (
33
+ <Alert
34
+ title={alertInfo.title}
35
+ type={alertInfo.alertType}
36
+ variant="alarm"
37
+ action={
38
+ <Button
39
+ id="widget-slippage-warning-error-change-settings-or-reset-slippage-btn"
40
+ size="xxsmall"
41
+ type={alertInfo.alertType}
42
+ onClick={() => onClickActionButton(alertInfo.action)}>
43
+ {alertInfo.actionButtonTitle}
44
+ </Button>
45
+ }
46
+ />
47
+ );
48
+ }
@@ -0,0 +1,3 @@
1
+ export interface PropTypes {
2
+ onChangeSettings: () => void;
3
+ }
@@ -17,8 +17,14 @@ import {
17
17
  DerivationPath,
18
18
  Namespaces,
19
19
  } from '../WalletStatefulConnect';
20
+ import { Detached } from '../WalletStatefulConnect/Detached';
20
21
 
21
- import { isOnDerivationPath, isOnNamespace, isOnStatus } from './helpers';
22
+ import {
23
+ isOnDerivationPath,
24
+ isOnDetached,
25
+ isOnNamespace,
26
+ isOnStatus,
27
+ } from './helpers';
22
28
 
23
29
  const KEEP_SUCCESS_MODAL_FOR = 3_000;
24
30
  const DELAY_SHOWING_MODAL_FOR = 300;
@@ -56,6 +62,10 @@ export function StatefulConnectModal(props: PropTypes) {
56
62
  .catch(catchErrorOnHandle);
57
63
  };
58
64
 
65
+ const handleDetachedConfirm = () => {
66
+ handleClosingModal();
67
+ };
68
+
59
69
  const handleDerivationPathConfirm = (derivationPath: string) => {
60
70
  if (!derivationPath) {
61
71
  throw new Error(
@@ -130,6 +140,7 @@ export function StatefulConnectModal(props: PropTypes) {
130
140
  .then((result) => {
131
141
  const resultIsNeedMoreStepsToConnect = [
132
142
  ResultStatus.Namespace,
143
+ ResultStatus.Detached,
133
144
  ResultStatus.DerivationPath,
134
145
  ].includes(result.status);
135
146
 
@@ -178,6 +189,13 @@ export function StatefulConnectModal(props: PropTypes) {
178
189
  value={getState().derivationPath}
179
190
  />
180
191
  )}
192
+ {isOnDetached(getState) && (
193
+ <Detached
194
+ onConfirm={handleDetachedConfirm}
195
+ value={getState().namespace}
196
+ selectedNamespaces={getState().selectedNamespaces}
197
+ />
198
+ )}
181
199
  </WatermarkedModal>
182
200
  );
183
201
  }
@@ -21,3 +21,9 @@ export function isOnDerivationPath(
21
21
  } {
22
22
  return getState().status === 'derivationPath';
23
23
  }
24
+
25
+ export function isOnDetached(
26
+ getState: () => State
27
+ ): getState is () => State & { namespace: NonNullable<State['namespace']> } {
28
+ return getState().status === 'detached';
29
+ }
@@ -1,2 +1,2 @@
1
1
  export { StatefulConnectModal } from './StatefulConnectModal';
2
- export { isOnNamespace, isOnDerivationPath } from './helpers';
2
+ export { isOnNamespace, isOnDerivationPath, isOnDetached } from './helpers';
@@ -0,0 +1,4 @@
1
+ export const USD_FORMAT_DECIMALS = 2;
2
+ export const USD_EXCHANGE_MINIMUM = 0.001;
3
+ export const SMALL_VALUE_DECIMALS = 14;
4
+ export const LARGE_VALUE_MAX_DIGITS = 10;
@@ -0,0 +1,76 @@
1
+ import type { SlippageColorParams } from './SwapMetrics.types';
2
+
3
+ import BigNumber from 'bignumber.js';
4
+
5
+ import { QuoteErrorType, QuoteWarningType } from '../../types';
6
+
7
+ import {
8
+ LARGE_VALUE_MAX_DIGITS,
9
+ SMALL_VALUE_DECIMALS,
10
+ USD_EXCHANGE_MINIMUM,
11
+ USD_FORMAT_DECIMALS,
12
+ } from './SwapMetrics.constants';
13
+
14
+ export function getSlippageColor(params: SlippageColorParams) {
15
+ const { error, isDarkTheme, warning } = params;
16
+ const { quoteError, slippageError } = error;
17
+ const { quoteWarning, slippageWarning } = warning;
18
+ const hasSlippageError =
19
+ !!slippageError ||
20
+ quoteError?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE;
21
+ const hasSlippageWarning =
22
+ !!slippageWarning ||
23
+ quoteWarning?.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE;
24
+
25
+ if (hasSlippageError) {
26
+ return '$error500';
27
+ } else if (hasSlippageWarning) {
28
+ return '$warning500';
29
+ }
30
+ if (isDarkTheme) {
31
+ return '$neutral600';
32
+ }
33
+ return '$neutral700';
34
+ }
35
+
36
+ export function getUsdExchangeRate(params: {
37
+ toTokenUsdPrice: number | null;
38
+ fromTokenUsdPrice: number | null;
39
+ }) {
40
+ const { toTokenUsdPrice, fromTokenUsdPrice } = params;
41
+ if (!toTokenUsdPrice || !fromTokenUsdPrice) {
42
+ return { rawValue: '0', displayValue: '0' };
43
+ }
44
+
45
+ const toPrice = new BigNumber(toTokenUsdPrice);
46
+ const fromPrice = new BigNumber(fromTokenUsdPrice);
47
+ const rawValue = toPrice.dividedBy(fromPrice);
48
+ let displayValue: string;
49
+
50
+ if (rawValue.isLessThan(1)) {
51
+ displayValue = rawValue.toFixed(SMALL_VALUE_DECIMALS);
52
+ } else if (rawValue.toFixed(0).length > LARGE_VALUE_MAX_DIGITS) {
53
+ displayValue = rawValue.toFixed(0).slice(0, LARGE_VALUE_MAX_DIGITS);
54
+ } else {
55
+ displayValue = rawValue.toFixed(USD_FORMAT_DECIMALS);
56
+ }
57
+ return {
58
+ displayValue,
59
+ rawValue: rawValue.toFixed(),
60
+ };
61
+ }
62
+
63
+ export function formatTokenValueInUsd(
64
+ usdExchangeRate: number,
65
+ tokenUsdPrice: number
66
+ ): string {
67
+ const value = new BigNumber(usdExchangeRate).multipliedBy(tokenUsdPrice);
68
+ if (value.isLessThan(USD_EXCHANGE_MINIMUM)) {
69
+ return '$0';
70
+ }
71
+ const result = value
72
+ .decimalPlaces(USD_FORMAT_DECIMALS, BigNumber.ROUND_DOWN)
73
+ .toFormat(USD_FORMAT_DECIMALS);
74
+
75
+ return `$${result}`;
76
+ }
@@ -0,0 +1,32 @@
1
+ import { darkTheme, styled, Typography } from '@rango-dev/ui';
2
+
3
+ export const Container = styled('div', {
4
+ display: 'flex',
5
+ padding: '$4',
6
+ justifyContent: 'space-between',
7
+ alignItems: 'center',
8
+ });
9
+
10
+ export const Rate = styled('div', {
11
+ display: 'flex',
12
+ alignItems: 'center',
13
+ gap: '$2',
14
+ '& .rate-text': {
15
+ color: '$neutral700',
16
+ [`.${darkTheme} &`]: {
17
+ color: '$neutral700',
18
+ },
19
+ },
20
+ '& ._icon-button': {
21
+ transform: 'rotate(90deg)',
22
+ width: '$16',
23
+ height: '$16',
24
+ },
25
+ });
26
+
27
+ export const TokenName = styled(Typography, {
28
+ maxWidth: '$32',
29
+ overflow: 'hidden',
30
+ textOverflow: 'ellipsis',
31
+ whiteSpace: 'nowrap',
32
+ });
@@ -0,0 +1,134 @@
1
+ import type { PropTypes } from './SwapMetrics.types';
2
+
3
+ import { i18n } from '@lingui/core';
4
+ import {
5
+ IconButton,
6
+ ReverseIcon,
7
+ Skeleton,
8
+ Tooltip,
9
+ Typography,
10
+ } from '@rango-dev/ui';
11
+ import React from 'react';
12
+
13
+ import { useTheme } from '../../hooks/useTheme';
14
+ import { useAppStore } from '../../store/AppStore';
15
+ import { getContainer } from '../../utils/common';
16
+ import { getSlippageValidation } from '../../utils/settings';
17
+
18
+ import {
19
+ formatTokenValueInUsd,
20
+ getSlippageColor,
21
+ getUsdExchangeRate,
22
+ } from './SwapMetrics.helpers';
23
+ import { Container, Rate, TokenName } from './SwapMetrics.styles';
24
+
25
+ export function SwapMetrics(props: PropTypes) {
26
+ const { slippage, customSlippage, quoteTokensRate, changeQuoteTokensRate } =
27
+ useAppStore();
28
+ const {
29
+ quoteError,
30
+ quoteWarning,
31
+ fromToken: initialFromToken,
32
+ toToken: initialToToken,
33
+ quote,
34
+ loading,
35
+ } = props;
36
+ const currentSlippage = customSlippage !== null ? customSlippage : slippage;
37
+ const { mode } = useTheme({});
38
+ const slippageValidation = getSlippageValidation(currentSlippage);
39
+ const isDarkTheme = mode === 'dark';
40
+ const isDefaultRate = quoteTokensRate === 'default';
41
+
42
+ const error = {
43
+ quoteError,
44
+ slippageError:
45
+ slippageValidation?.type === 'error' ? slippageValidation.message : null,
46
+ };
47
+ const warning = {
48
+ quoteWarning,
49
+ slippageWarning:
50
+ slippageValidation?.type === 'warning'
51
+ ? slippageValidation.message
52
+ : null,
53
+ };
54
+
55
+ const sourceToken = quote?.swaps[0].from || initialFromToken;
56
+ const destinationToken =
57
+ quote?.swaps[quote?.swaps.length - 1].to || initialToToken;
58
+
59
+ const fromToken = isDefaultRate ? sourceToken : destinationToken;
60
+ const toToken = isDefaultRate ? destinationToken : sourceToken;
61
+
62
+ const fromAmount = Number(
63
+ isDefaultRate ? quote?.outputAmount : quote?.requestAmount
64
+ );
65
+ const toAmount = Number(
66
+ isDefaultRate ? quote?.requestAmount : quote?.outputAmount
67
+ );
68
+
69
+ const fromTokenUsdPrice = fromAmount || fromToken.usdPrice;
70
+ const toTokenUsdPrice = toAmount || toToken.usdPrice;
71
+
72
+ const { rawValue: rawExchangeRate, displayValue: displayExchangeRate } =
73
+ getUsdExchangeRate({
74
+ toTokenUsdPrice,
75
+ fromTokenUsdPrice,
76
+ });
77
+
78
+ return (
79
+ <Container>
80
+ <Typography
81
+ variant={!!error || !!warning ? 'label' : 'body'}
82
+ size={!!error || !!warning ? 'medium' : 'small'}
83
+ color={getSlippageColor({ error, warning, isDarkTheme })}>
84
+ {i18n.t('Slippage:')} {currentSlippage}%
85
+ </Typography>
86
+ {loading ? (
87
+ <Skeleton height={16} width={104} variant="rounded" />
88
+ ) : (
89
+ fromTokenUsdPrice &&
90
+ toTokenUsdPrice && (
91
+ <Rate>
92
+ <Typography className="rate-text" variant="body" size="small">
93
+ 1
94
+ </Typography>
95
+ <TokenName className="rate-text" variant="body" size="small">
96
+ {toToken.symbol}
97
+ </TokenName>
98
+ <IconButton
99
+ id="widget-home-page-change-rate-button"
100
+ onClick={changeQuoteTokensRate}>
101
+ <ReverseIcon size={14} color="secondary" />
102
+ </IconButton>
103
+ <Tooltip
104
+ container={getContainer()}
105
+ side="top"
106
+ sideOffset={4}
107
+ content={
108
+ <Typography className="rate-text" variant="body" size="small">
109
+ {rawExchangeRate}
110
+ </Typography>
111
+ }>
112
+ <Typography className="rate-text" variant="body" size="small">
113
+ {displayExchangeRate}
114
+ </Typography>
115
+ </Tooltip>
116
+
117
+ <TokenName className="rate-text" variant="body" size="small">
118
+ {fromToken.symbol}
119
+ </TokenName>
120
+ {fromToken.usdPrice && (
121
+ <Typography color="neutral600" variant="body" size="small">
122
+ ~
123
+ {formatTokenValueInUsd(
124
+ Number(rawExchangeRate),
125
+ fromToken.usdPrice
126
+ )}
127
+ </Typography>
128
+ )}
129
+ </Rate>
130
+ )
131
+ )}
132
+ </Container>
133
+ );
134
+ }
@@ -0,0 +1,26 @@
1
+ import type { QuoteError, QuoteWarning, SelectedQuote } from '../../types';
2
+ import type { TokenData } from '../TokenList/TokenList.types';
3
+ import type { SwapResultAsset } from 'rango-sdk';
4
+
5
+ export interface PropTypes {
6
+ quoteError: QuoteError | null;
7
+ quoteWarning: QuoteWarning | null;
8
+ fromToken: TokenData;
9
+ toToken: TokenData;
10
+ quote: SelectedQuote | null;
11
+ loading: boolean;
12
+ }
13
+
14
+ export type Tokens = {
15
+ to: TokenData | SwapResultAsset;
16
+ from: TokenData | SwapResultAsset;
17
+ };
18
+
19
+ export type SlippageColorParams = {
20
+ error: { quoteError: QuoteError | null; slippageError: string | null };
21
+ warning: {
22
+ quoteWarning: QuoteWarning | null;
23
+ slippageWarning: string | null;
24
+ };
25
+ isDarkTheme: boolean;
26
+ };
@@ -0,0 +1 @@
1
+ export { SwapMetrics } from './SwapMetrics';
@@ -0,0 +1,53 @@
1
+ import type { PropTypes } from './Detached.types';
2
+
3
+ import { i18n } from '@lingui/core';
4
+ import { Divider, Image, MessageBox } from '@rango-dev/ui';
5
+ import React from 'react';
6
+
7
+ import { NamespaceDetachedItem } from './NamespaceDetachedItem';
8
+ import { NamespaceList, StyledButton } from './Namespaces.styles';
9
+ import { NamespaceUnsupportedItem } from './NamespaceUnsupportedItem';
10
+
11
+ export function Detached(props: PropTypes) {
12
+ const { selectedNamespaces, value } = props;
13
+ const { targetWallet } = value;
14
+
15
+ return (
16
+ <>
17
+ <MessageBox
18
+ type="info"
19
+ title={i18n.t(`Connect {wallet}`, {
20
+ wallet: targetWallet.type,
21
+ })}
22
+ description={i18n.t(
23
+ 'This wallet supports multiple chains. Choose which chains you’d like to connect or disconnect.'
24
+ )}
25
+ icon={<Image src={targetWallet.image} size={45} />}
26
+ />
27
+ <Divider size={20} />
28
+ <NamespaceList>
29
+ {targetWallet.needsNamespace?.data.map((namespace, index, array) => (
30
+ <React.Fragment key={namespace.id}>
31
+ {namespace.unsupported ? (
32
+ <NamespaceUnsupportedItem namespace={namespace} />
33
+ ) : (
34
+ <NamespaceDetachedItem
35
+ walletType={targetWallet.type}
36
+ namespace={namespace}
37
+ initialConnect={selectedNamespaces?.includes(namespace.value)}
38
+ />
39
+ )}
40
+ {index !== array.length - 1 && <Divider size={10} />}
41
+ </React.Fragment>
42
+ ))}
43
+ </NamespaceList>
44
+ <Divider size={20} />
45
+ <StyledButton
46
+ id="widget-name-space-confirm-btn"
47
+ type="primary"
48
+ onClick={props.onConfirm}>
49
+ {i18n.t('Done')}
50
+ </StyledButton>
51
+ </>
52
+ );
53
+ }
@@ -0,0 +1,8 @@
1
+ import type { NeedsNamespacesState } from '../../hooks/useStatefulConnect';
2
+ import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';
3
+
4
+ export interface PropTypes {
5
+ value: NeedsNamespacesState;
6
+ onConfirm: () => void;
7
+ selectedNamespaces: Namespace[] | null;
8
+ }
@@ -0,0 +1,177 @@
1
+ import type { NamespaceDetachedItemPropTypes } from './Namespaces.types';
2
+ import type { NamespaceData } from '@rango-dev/wallets-core/dist/hub/store/namespaces';
3
+ import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';
4
+
5
+ import { i18n } from '@lingui/core';
6
+ import {
7
+ Button,
8
+ ChevronDownIcon,
9
+ ChevronUpIcon,
10
+ Divider,
11
+ Spinner,
12
+ Typography,
13
+ } from '@rango-dev/ui';
14
+ import { useWallets } from '@rango-dev/wallets-react';
15
+ import React, { useEffect, useLayoutEffect, useState } from 'react';
16
+
17
+ import { useAppStore } from '../../store/AppStore';
18
+ import { getConciseAddress } from '../../utils/wallets';
19
+
20
+ import { getBlockchainLogo } from './Namespaces.helpers';
21
+ import {
22
+ NamespaceAccountAddress,
23
+ NamespaceDetachedItemInfo,
24
+ NamespaceItemContainer,
25
+ NamespaceItemContent,
26
+ NamespaceItemError,
27
+ NamespaceItemErrorDropdownToggle,
28
+ NamespaceItemInnerContent,
29
+ NamespaceLogo,
30
+ } from './Namespaces.styles';
31
+ import { SupportedChainsList } from './SupportedChainsList';
32
+
33
+ export const NamespaceDetachedItem = function NamespaceDetachedItem(
34
+ props: NamespaceDetachedItemPropTypes
35
+ ) {
36
+ const { walletType, namespace, initialConnect } = props;
37
+ const blockchains = useAppStore().blockchains();
38
+ const { connect, disconnect, state } = useWallets();
39
+ const [error, setError] = useState<Error | null>(null);
40
+ const [errorIsExpanded, setErrorIsExpanded] = useState(false);
41
+
42
+ const walletState = state(walletType);
43
+
44
+ const namespaceState = walletState.namespaces?.get(namespace.value);
45
+ const firstAccountArray = namespaceState.accounts?.[0]?.split(':');
46
+
47
+ useEffect(() => setErrorIsExpanded(false), [error]);
48
+
49
+ useLayoutEffect(() => {
50
+ if (initialConnect) {
51
+ void handleConnectNamespace(walletType, namespace.value);
52
+ }
53
+ }, []);
54
+
55
+ const handleConnectNamespace = async (
56
+ walletType: string,
57
+ namespace: Namespace
58
+ ) => {
59
+ try {
60
+ await connect(walletType, [
61
+ {
62
+ namespace: namespace,
63
+ network: '',
64
+ },
65
+ ]);
66
+ } catch (error) {
67
+ setError(error as Error);
68
+ }
69
+ };
70
+
71
+ const handleButtonClick = async (namespaceState: NamespaceData) => {
72
+ setError(null);
73
+ if (namespaceState.connected) {
74
+ await disconnect(walletType, [namespace.value]);
75
+ } else {
76
+ void handleConnectNamespace(walletType, namespace.value);
77
+ }
78
+ };
79
+
80
+ const getButtonText = () => {
81
+ if (namespaceState.connected) {
82
+ return i18n.t('Disconnect');
83
+ }
84
+ if (!!error) {
85
+ return i18n.t('Try again');
86
+ }
87
+ return i18n.t('Connect');
88
+ };
89
+
90
+ return (
91
+ <NamespaceItemContainer hasError={!!error}>
92
+ <NamespaceItemContent>
93
+ <NamespaceLogo
94
+ src={getBlockchainLogo(blockchains, namespace.id)}
95
+ size={40}
96
+ />
97
+ <NamespaceItemInnerContent>
98
+ <NamespaceDetachedItemInfo>
99
+ <Typography variant="label" size="large">
100
+ {namespace.label}
101
+ </Typography>
102
+ {namespaceState.connected && (
103
+ <Typography variant="body" size="small" color="success500">
104
+ {i18n.t('Connected')}
105
+ </Typography>
106
+ )}
107
+ {!namespaceState.connected && !!error && (
108
+ <Typography variant="body" size="small" color="error500">
109
+ {i18n.t('Connection failed')}
110
+ </Typography>
111
+ )}
112
+ </NamespaceDetachedItemInfo>
113
+ {namespaceState.connected && (
114
+ <NamespaceAccountAddress
115
+ variant="body"
116
+ size="small"
117
+ color="neutral700">
118
+ {getConciseAddress(
119
+ firstAccountArray?.[firstAccountArray?.length - 1]
120
+ )}
121
+ </NamespaceAccountAddress>
122
+ )}
123
+ {!namespaceState.connected && error && (
124
+ <NamespaceItemErrorDropdownToggle
125
+ onClick={() =>
126
+ setErrorIsExpanded((errorIsExpanded) => !errorIsExpanded)
127
+ }>
128
+ <Typography
129
+ variant="body"
130
+ size="small"
131
+ color="neutral700"
132
+ style={{
133
+ textDecoration: 'underline',
134
+ userSelect: 'none',
135
+ textDecorationSkipInk: 'none',
136
+ }}>
137
+ {i18n.t('See why')}
138
+ </Typography>
139
+ {errorIsExpanded ? (
140
+ <ChevronUpIcon size={12} color="gray" />
141
+ ) : (
142
+ <ChevronDownIcon size={12} color="gray" />
143
+ )}
144
+ </NamespaceItemErrorDropdownToggle>
145
+ )}
146
+ {!namespaceState.connected &&
147
+ !error &&
148
+ namespace.chains.length > 1 && (
149
+ <SupportedChainsList chains={namespace.chains} />
150
+ )}
151
+ </NamespaceItemInnerContent>
152
+ {namespaceState.connecting ? (
153
+ <Spinner color="info" />
154
+ ) : (
155
+ <Button
156
+ id="widget-name-space-connect-btn"
157
+ variant="ghost"
158
+ type={namespaceState.connected ? 'error' : 'primary'}
159
+ size="small"
160
+ onClick={async () => handleButtonClick(namespaceState)}>
161
+ {getButtonText()}
162
+ </Button>
163
+ )}
164
+ </NamespaceItemContent>
165
+ {!namespaceState.connected && !!error && errorIsExpanded && (
166
+ <>
167
+ <Divider size={4} />
168
+ <NamespaceItemError>
169
+ <Typography variant="body" size="small" color="neutral700">
170
+ {(error.cause as Error)?.message || error.message}
171
+ </Typography>
172
+ </NamespaceItemError>
173
+ </>
174
+ )}
175
+ </NamespaceItemContainer>
176
+ );
177
+ };