@rango-dev/widget-embedded 0.43.1-next.0 → 0.43.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 (144) hide show
  1. package/dist/components/BlockchainList/BlockchainList.d.ts.map +1 -1
  2. package/dist/components/BlockchainSelectorButton/BlockchainSelectorButton.d.ts.map +1 -1
  3. package/dist/components/BlockchainsSection/BlockchainsSection.d.ts.map +1 -1
  4. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  5. package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
  6. package/dist/components/CustomDestination/CustomDestination.d.ts.map +1 -1
  7. package/dist/components/CustomDestination/CustomDestination.styles.d.ts +1 -0
  8. package/dist/components/CustomDestination/CustomDestination.styles.d.ts.map +1 -1
  9. package/dist/components/CustomTokenModal/CustomTokenModal.d.ts.map +1 -1
  10. package/dist/components/FilterSelector/FilterSelectorContent.d.ts.map +1 -1
  11. package/dist/components/HeaderButtons/NotificationsBadge.d.ts.map +1 -1
  12. package/dist/components/HistoryGroupedList/HistoryGroupedList.d.ts.map +1 -1
  13. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  14. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  15. package/dist/components/Quote/Quote.d.ts.map +1 -1
  16. package/dist/components/Quote/Quote.types.d.ts +2 -1
  17. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  18. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
  19. package/dist/components/Quote/QuoteSummary.d.ts.map +1 -1
  20. package/dist/components/Quote/QuoteTrigger.d.ts.map +1 -1
  21. package/dist/components/QuoteWarningsAndErrors/HighValueLossWarningModal.d.ts.map +1 -1
  22. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.d.ts.map +1 -1
  23. package/dist/components/QuoteWarningsAndErrors/SlippageWariningModal.d.ts.map +1 -1
  24. package/dist/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.d.ts.map +1 -1
  25. package/dist/components/Quotes/Quotes.d.ts.map +1 -1
  26. package/dist/components/Quotes/SelectStrategy.d.ts.map +1 -1
  27. package/dist/components/RefreshModal/RefreshModal.d.ts.map +1 -1
  28. package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
  29. package/dist/components/Slippage/Slippage.d.ts.map +1 -1
  30. package/dist/components/StatefulConnectModal/StatefulConnectModal.d.ts +1 -0
  31. package/dist/components/StatefulConnectModal/StatefulConnectModal.d.ts.map +1 -1
  32. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  33. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.Failed.d.ts.map +1 -1
  34. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.d.ts.map +1 -1
  35. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.d.ts.map +1 -1
  36. package/dist/components/SwapDetailsModal/SwapDetailsCompleteModal.d.ts.map +1 -1
  37. package/dist/components/SwapDetailsModal/SwapDetailsModal.WalletState.d.ts.map +1 -1
  38. package/dist/components/SwapDetailsModal/SwapDetailsModal.d.ts.map +1 -1
  39. package/dist/components/SwapDetailsModal/SwapDetailsModal.helpers.d.ts.map +1 -1
  40. package/dist/components/SwapMetrics/SwapMetrics.helpers.d.ts.map +1 -1
  41. package/dist/components/SwitchFromAndTo/SwitchFromAndTo.d.ts.map +1 -1
  42. package/dist/components/WalletStatefulConnect/DerivationPath.d.ts.map +1 -1
  43. package/dist/components/WalletStatefulConnect/ExperimentalChain.d.ts +1 -0
  44. package/dist/components/WalletStatefulConnect/ExperimentalChain.d.ts.map +1 -1
  45. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts.map +1 -1
  46. package/dist/components/WalletStatefulConnect/NamespaceListItem.d.ts.map +1 -1
  47. package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
  48. package/dist/components/WalletStatefulConnect/SupportedChainsList.types.d.ts +2 -2
  49. package/dist/components/WalletStatefulConnect/SupportedChainsList.types.d.ts.map +1 -1
  50. package/dist/components/common/ActivateTabModal/ActivateTabModal.d.ts.map +1 -1
  51. package/dist/containers/Inputs/Inputs.d.ts.map +1 -1
  52. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  53. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +1 -0
  54. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  55. package/dist/containers/Settings/Lists.d.ts.map +1 -1
  56. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
  57. package/dist/index.js +2 -2
  58. package/dist/index.js.map +3 -3
  59. package/dist/pages/AddCustomTokenPage.d.ts.map +1 -1
  60. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  61. package/dist/pages/CustomTokensPage.d.ts.map +1 -1
  62. package/dist/pages/HistoryPage.d.ts.map +1 -1
  63. package/dist/pages/Home.d.ts.map +1 -1
  64. package/dist/pages/LanguagePage.d.ts.map +1 -1
  65. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  66. package/dist/pages/SelectBlockchainPage.d.ts.map +1 -1
  67. package/dist/pages/SelectSwapItemPage/SelectSwapItemsPage.d.ts.map +1 -1
  68. package/dist/pages/SettingsPage.d.ts.map +1 -1
  69. package/dist/pages/WalletsPage.d.ts.map +1 -1
  70. package/dist/store/slices/wallets.d.ts +1 -0
  71. package/dist/store/slices/wallets.d.ts.map +1 -1
  72. package/dist/types/config.d.ts +1 -1
  73. package/dist/utils/swap.d.ts.map +1 -1
  74. package/dist/widget-embedded.build.json +1 -1
  75. package/package.json +10 -10
  76. package/src/components/BlockchainList/BlockchainList.tsx +4 -1
  77. package/src/components/BlockchainList/LoadingBlockchainList.tsx +1 -1
  78. package/src/components/BlockchainSelectorButton/BlockchainSelectorButton.tsx +2 -1
  79. package/src/components/BlockchainsSection/BlockchainsSection.tsx +8 -2
  80. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +8 -1
  81. package/src/components/ConfirmWalletsModal/WalletList.tsx +10 -4
  82. package/src/components/CustomDestination/CustomDestination.tsx +2 -1
  83. package/src/components/CustomTokenModal/CustomTokenModal.tsx +1 -0
  84. package/src/components/FilterSelector/FilterSelectorContent.tsx +1 -0
  85. package/src/components/HeaderButtons/InProgressTransactionBadge.tsx +1 -1
  86. package/src/components/HeaderButtons/NotificationsBadge.tsx +5 -1
  87. package/src/components/HistoryGroupedList/HistoryGroupedList.tsx +1 -0
  88. package/src/components/ImportCustomToken/ImportCustomToken.tsx +1 -1
  89. package/src/components/NoResult/NoResult.tsx +2 -1
  90. package/src/components/NotificationContent/NotificationContent.tsx +1 -0
  91. package/src/components/Quote/Quote.tsx +8 -2
  92. package/src/components/Quote/Quote.types.ts +2 -1
  93. package/src/components/Quote/QuoteCostDetails.tsx +9 -3
  94. package/src/components/Quote/QuoteSummary.tsx +2 -0
  95. package/src/components/Quote/QuoteTrigger.tsx +1 -0
  96. package/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx +1 -0
  97. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx +1 -0
  98. package/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx +1 -0
  99. package/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx +1 -0
  100. package/src/components/Quotes/Quotes.tsx +1 -0
  101. package/src/components/Quotes/SelectStrategy.tsx +1 -0
  102. package/src/components/RefreshModal/RefreshModal.tsx +2 -0
  103. package/src/components/SearchInput/SearchInput.tsx +7 -2
  104. package/src/components/Slippage/Slippage.tsx +3 -0
  105. package/src/components/StatefulConnectModal/StatefulConnectModal.tsx +2 -0
  106. package/src/components/SwapDetails/SwapDetails.tsx +2 -1
  107. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Failed.tsx +2 -0
  108. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx +9 -1
  109. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx +8 -1
  110. package/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx +2 -0
  111. package/src/components/SwapDetailsModal/SwapDetailsModal.WalletState.tsx +1 -0
  112. package/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx +4 -0
  113. package/src/components/SwapDetailsModal/SwapDetailsModal.tsx +1 -0
  114. package/src/components/SwapMetrics/SwapMetrics.helpers.ts +6 -2
  115. package/src/components/SwitchFromAndTo/SwitchFromAndTo.tsx +1 -0
  116. package/src/components/WalletStatefulConnect/DerivationPath.tsx +2 -0
  117. package/src/components/WalletStatefulConnect/Detached.tsx +1 -1
  118. package/src/components/WalletStatefulConnect/ExperimentalChain.tsx +3 -1
  119. package/src/components/WalletStatefulConnect/NamespaceDetachedItem.tsx +7 -4
  120. package/src/components/WalletStatefulConnect/NamespaceListItem.tsx +7 -3
  121. package/src/components/WalletStatefulConnect/Namespaces.tsx +35 -25
  122. package/src/components/WalletStatefulConnect/SupportedChainsList.tsx +1 -1
  123. package/src/components/WalletStatefulConnect/SupportedChainsList.types.ts +2 -2
  124. package/src/components/common/ActivateTabModal/ActivateTabModal.tsx +1 -0
  125. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +1 -1
  126. package/src/containers/Inputs/Inputs.tsx +2 -0
  127. package/src/containers/QuoteInfo/QuoteInfo.tsx +2 -1
  128. package/src/containers/QuoteInfo/QuoteInfo.types.ts +1 -0
  129. package/src/containers/Settings/Lists.tsx +13 -3
  130. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +25 -23
  131. package/src/pages/AddCustomTokenPage.tsx +7 -1
  132. package/src/pages/ConfirmSwapPage.tsx +9 -1
  133. package/src/pages/CustomTokensPage.tsx +2 -0
  134. package/src/pages/HistoryPage.tsx +2 -0
  135. package/src/pages/Home.tsx +1 -0
  136. package/src/pages/LanguagePage.tsx +2 -0
  137. package/src/pages/LiquiditySourcePage.tsx +6 -1
  138. package/src/pages/SelectBlockchainPage.tsx +1 -0
  139. package/src/pages/SelectSwapItemPage/SelectSwapItemsPage.tsx +1 -0
  140. package/src/pages/SettingsPage.tsx +1 -0
  141. package/src/pages/WalletsPage.tsx +1 -0
  142. package/src/store/slices/wallets.ts +2 -0
  143. package/src/types/config.ts +1 -1
  144. package/src/utils/swap.ts +2 -1
@@ -11,6 +11,7 @@ export function WarningAlert(props: WaningAlertsProps) {
11
11
  return (
12
12
  <Alert
13
13
  type="warning"
14
+ id="widget-swap-details-change-network-alert"
14
15
  title={message.shortMessage}
15
16
  action={
16
17
  <Button
@@ -36,6 +37,7 @@ export function WarningAlert(props: WaningAlertsProps) {
36
37
  <Alert
37
38
  type="warning"
38
39
  title={message.shortMessage}
40
+ id="widget-swap-details-warning-alert-connect-wallet-alert"
39
41
  action={
40
42
  <Button
41
43
  id="widget-swap-details-warning-alert-connect-wallet-btn"
@@ -53,5 +55,11 @@ export function WarningAlert(props: WaningAlertsProps) {
53
55
  );
54
56
  }
55
57
 
56
- return <Alert type="warning" title={message.shortMessage} />;
58
+ return (
59
+ <Alert
60
+ id="widget-swap-details-short-alert"
61
+ type="warning"
62
+ title={message.shortMessage}
63
+ />
64
+ );
57
65
  }
@@ -40,6 +40,7 @@ export function SwapDetailsAlerts(props: SwapAlertsProps) {
40
40
  return (
41
41
  <Fragment key={key}>
42
42
  <Alert
43
+ id="widget-swap-details-tx-alert"
43
44
  type={
44
45
  lastUrl
45
46
  ? (loading && 'loading') || (error && 'error') || 'success'
@@ -65,7 +66,13 @@ export function SwapDetailsAlerts(props: SwapAlertsProps) {
65
66
  </Fragment>
66
67
  );
67
68
  })}
68
- {waitingProgress && <Alert type="loading" title={message.shortMessage} />}
69
+ {waitingProgress && (
70
+ <Alert
71
+ id="widget-swap-details-loading-alert"
72
+ type="loading"
73
+ title={message.shortMessage}
74
+ />
75
+ )}
69
76
  {step.status !== 'failed' && hasWarning && (
70
77
  <WarningAlert
71
78
  switchNetwork={switchNetwork}
@@ -44,6 +44,7 @@ export function SwapDetailsCompleteModal(props: CompleteModalPropTypes) {
44
44
  <WatermarkedModal
45
45
  open={open}
46
46
  onClose={onClose}
47
+ id="widget-swap-details-complete-modal"
47
48
  container={
48
49
  document.getElementById(WIDGET_UI_ID.SWAP_BOX_ID) || document.body
49
50
  }>
@@ -52,6 +53,7 @@ export function SwapDetailsCompleteModal(props: CompleteModalPropTypes) {
52
53
  <TokenAmount
53
54
  direction="vertical"
54
55
  tooltipContainer={getContainer()}
56
+ id="widget-swap-details-complete-modal-success-token-amount-container"
55
57
  type="output"
56
58
  centerAlign={true}
57
59
  price={{
@@ -73,6 +73,7 @@ export const WalletStateContent = (props: WalletStateContentProps) => {
73
73
  </WalletContainer>
74
74
  )}
75
75
  <StatefulConnectModal
76
+ id="widget-swap-details-modal"
76
77
  wallet={selectedWalletToConnect}
77
78
  onClose={() => {
78
79
  setSelectedWalletToConnect(undefined);
@@ -19,4 +19,8 @@ export const modalNetworkValues: Record<
19
19
  type: 'success',
20
20
  title: i18n.t('Network Changed'),
21
21
  },
22
+ [PendingSwapNetworkStatus.NetworkChangeFailed]: {
23
+ type: 'warning',
24
+ title: i18n.t('Network Change Failed'),
25
+ },
22
26
  };
@@ -29,6 +29,7 @@ export function SwapDetailsModal(props: ModalPropTypes) {
29
29
 
30
30
  return (
31
31
  <WatermarkedModal
32
+ id="widget-swap-details-modal"
32
33
  open={!!state}
33
34
  onClose={onClose}
34
35
  container={
@@ -41,14 +41,18 @@ export function getUsdExchangeRate(params: {
41
41
  if (!toTokenUsdPrice || !fromTokenUsdPrice) {
42
42
  return { rawValue: '0', displayValue: '0' };
43
43
  }
44
-
45
44
  const toPrice = new BigNumber(toTokenUsdPrice);
46
45
  const fromPrice = new BigNumber(fromTokenUsdPrice);
47
46
  const rawValue = toPrice.dividedBy(fromPrice);
48
47
  let displayValue: string;
49
48
 
50
49
  if (rawValue.isLessThan(1)) {
51
- displayValue = rawValue.toFixed(SMALL_VALUE_DECIMALS);
50
+ /*
51
+ * Format the number with up to SMALL_VALUE_DECIMALS digits after the decimal point,
52
+ * then remove any trailing zeros.
53
+ * Example: "0.120000" → "0.12", "0.00000000000010" → "0.0000000000001"
54
+ */
55
+ displayValue = rawValue.toFixed(SMALL_VALUE_DECIMALS).replace(/\.?0+$/, '');
52
56
  } else if (rawValue.toFixed(0).length > LARGE_VALUE_MAX_DIGITS) {
53
57
  displayValue = rawValue.toFixed(0).slice(0, LARGE_VALUE_MAX_DIGITS);
54
58
  } else {
@@ -15,6 +15,7 @@ export function SwitchFromAndToButton() {
15
15
  return (
16
16
  <SwitchButtonContainer>
17
17
  <StyledButton
18
+ id="widget-switch-from-and-to-btn"
18
19
  onClick={(event) => {
19
20
  const button = event.currentTarget;
20
21
 
@@ -100,6 +100,7 @@ export function DerivationPath(props: PropTypes) {
100
100
  {i18n.t('Choose Derivation Path Template')}
101
101
  </InputLabel>
102
102
  <Select
103
+ id="widget-derivation-path-template-select"
103
104
  value={selectedDerivationPathId || ''}
104
105
  options={derivationPaths.map((derivationPath) => ({
105
106
  value: derivationPath.id,
@@ -116,6 +117,7 @@ export function DerivationPath(props: PropTypes) {
116
117
  : i18n.t('Enter Index')}
117
118
  </InputLabel>
118
119
  <TextField
120
+ id="widget-derivation-path-template-input"
119
121
  type={isCustomOptionSelected ? 'text' : 'number'}
120
122
  variant="contained"
121
123
  value={derivationPathIndex}
@@ -25,7 +25,7 @@ export function Detached(props: PropTypes) {
25
25
  icon={<Image src={targetWallet.image} size={45} />}
26
26
  />
27
27
  <Divider size={20} />
28
- <NamespaceList>
28
+ <NamespaceList id="widget-detached-namespace-list" as={'ul'}>
29
29
  {targetWallet.needsNamespace?.data.map((namespace, index, array) => (
30
30
  <React.Fragment key={namespace.id}>
31
31
  {namespace.unsupported ? (
@@ -5,13 +5,15 @@ import React from 'react';
5
5
  interface PropTypes {
6
6
  displayName?: string;
7
7
  onConfirm: () => void;
8
+ id: string;
8
9
  }
9
10
 
10
11
  export function ExperimentalChain(props: PropTypes) {
11
- const { displayName, onConfirm } = props;
12
+ const { displayName, onConfirm, id } = props;
12
13
 
13
14
  return (
14
15
  <MessageBox
16
+ id={id}
15
17
  title={i18n.t({
16
18
  id: 'Add {blockchainDisplayName} Chain',
17
19
  values: { blockchainDisplayName: displayName },
@@ -44,6 +44,8 @@ export const NamespaceDetachedItem = function NamespaceDetachedItem(
44
44
  const namespaceState = walletState.namespaces?.get(namespace.value);
45
45
  const firstAccountArray = namespaceState.accounts?.[0]?.split(':');
46
46
 
47
+ const supportedChains = namespace.getSupportedChains(blockchains);
48
+
47
49
  useEffect(() => setErrorIsExpanded(false), [error]);
48
50
 
49
51
  useLayoutEffect(() => {
@@ -95,7 +97,7 @@ export const NamespaceDetachedItem = function NamespaceDetachedItem(
95
97
  size={40}
96
98
  />
97
99
  <NamespaceItemInnerContent>
98
- <NamespaceDetachedItemInfo>
100
+ <NamespaceDetachedItemInfo className="widget-namespace-detached-item-info-div">
99
101
  <Typography variant="label" size="large">
100
102
  {namespace.label}
101
103
  </Typography>
@@ -122,6 +124,7 @@ export const NamespaceDetachedItem = function NamespaceDetachedItem(
122
124
  )}
123
125
  {!namespaceState.connected && error && (
124
126
  <NamespaceItemErrorDropdownToggle
127
+ className="widget-namespace-detached-item-error-toggle-btn"
125
128
  onClick={() =>
126
129
  setErrorIsExpanded((errorIsExpanded) => !errorIsExpanded)
127
130
  }>
@@ -145,8 +148,8 @@ export const NamespaceDetachedItem = function NamespaceDetachedItem(
145
148
  )}
146
149
  {!namespaceState.connected &&
147
150
  !error &&
148
- namespace.chains.length > 1 && (
149
- <SupportedChainsList chains={namespace.chains} />
151
+ supportedChains.length > 1 && (
152
+ <SupportedChainsList chains={supportedChains} />
150
153
  )}
151
154
  </NamespaceItemInnerContent>
152
155
  {namespaceState.connecting ? (
@@ -165,7 +168,7 @@ export const NamespaceDetachedItem = function NamespaceDetachedItem(
165
168
  {!namespaceState.connected && !!error && errorIsExpanded && (
166
169
  <>
167
170
  <Divider size={4} />
168
- <NamespaceItemError>
171
+ <NamespaceItemError id="widget-namespace-item-error-div">
169
172
  <Typography variant="body" size="small" color="neutral700">
170
173
  {(error.cause as Error)?.message || error.message}
171
174
  </Typography>
@@ -18,9 +18,13 @@ export function NamespaceListItem(props: NamespaceItemPropTypes) {
18
18
  const { onClick, type, namespace } = props;
19
19
  const blockchains = useAppStore().blockchains();
20
20
 
21
- const showSupportedChains = namespace.chains.length > 1;
21
+ const supportedChains = namespace.getSupportedChains(blockchains);
22
+ const showSupportedChains = supportedChains.length > 1;
22
23
  return (
23
- <NamespaceItemContainer onClick={onClick} clickable>
24
+ <NamespaceItemContainer
25
+ onClick={onClick}
26
+ clickable
27
+ className="widget-namespace-list-item">
24
28
  <NamespaceItemContent>
25
29
  <NamespaceLogo
26
30
  src={getBlockchainLogo(blockchains, namespace.id)}
@@ -31,7 +35,7 @@ export function NamespaceListItem(props: NamespaceItemPropTypes) {
31
35
  {namespace.label}
32
36
  </Typography>
33
37
  {showSupportedChains && (
34
- <SupportedChainsList chains={namespace.chains} />
38
+ <SupportedChainsList chains={supportedChains} />
35
39
  )}
36
40
  </NamespaceItemInnerContent>
37
41
  {type === 'radio' ? (
@@ -12,21 +12,30 @@ import {
12
12
  } from '@rango-dev/ui';
13
13
  import React, { useEffect, useMemo, useState } from 'react';
14
14
 
15
+ import { useAppStore } from '../../store/AppStore';
16
+
15
17
  import { NamespaceListItem } from './NamespaceListItem';
16
18
  import { NamespaceList, StyledButton } from './Namespaces.styles';
17
19
  import { NamespaceUnsupportedItem } from './NamespaceUnsupportedItem';
18
20
 
19
21
  export function Namespaces(props: PropTypes) {
20
22
  const { targetWallet } = props.value;
21
- const singleNamespace = targetWallet.needsNamespace?.selection === 'single';
23
+ const namespacesProperty = targetWallet.properties?.find(
24
+ (property) => property.name === 'namespaces'
25
+ );
26
+ const isHub = targetWallet.isHub;
27
+ const singleNamespace = targetWallet.isHub
28
+ ? namespacesProperty?.value.selection === 'single'
29
+ : targetWallet.needsNamespace?.selection === 'single';
30
+ const needsNamespace = isHub
31
+ ? namespacesProperty?.value
32
+ : targetWallet.needsNamespace;
22
33
  const providerImage = targetWallet.image;
23
34
 
35
+ const blockchains = useAppStore().blockchains();
24
36
  const [selectedNamespaces, setSelectedNamespaces] = useState<Namespace[]>([]);
25
37
  const supportedNamespaces = useMemo(
26
- () =>
27
- targetWallet.needsNamespace?.data.filter(
28
- (namespace) => !namespace.unsupported
29
- ),
38
+ () => needsNamespace?.data.filter((namespace) => !namespace.unsupported),
30
39
  [targetWallet?.type]
31
40
  );
32
41
 
@@ -73,9 +82,11 @@ export function Namespaces(props: PropTypes) {
73
82
  if (!!props.value.defaultSelectedChains?.length) {
74
83
  const namespacesContainingDefaultSelectedChains =
75
84
  supportedNamespaces.filter((namespace) =>
76
- namespace.chains.some((chain) =>
77
- props.value.defaultSelectedChains?.includes(chain.name)
78
- )
85
+ namespace
86
+ .getSupportedChains(blockchains)
87
+ .some((chain) =>
88
+ props.value.defaultSelectedChains?.includes(chain.name)
89
+ )
79
90
  );
80
91
  setSelectedNamespaces(
81
92
  namespacesContainingDefaultSelectedChains.map(
@@ -106,6 +117,7 @@ export function Namespaces(props: PropTypes) {
106
117
  <>
107
118
  <Divider size={20} />
108
119
  <Alert
120
+ id="widget-wallet-stateful-connect-alert"
109
121
  variant="alarm"
110
122
  type="info"
111
123
  title={i18n.t(
@@ -132,23 +144,21 @@ export function Namespaces(props: PropTypes) {
132
144
  <NamespaceList>
133
145
  {wrapRadioRoot(
134
146
  <>
135
- {targetWallet.needsNamespace?.data.map(
136
- (namespace, index, array) => (
137
- <React.Fragment key={namespace.id}>
138
- {namespace.unsupported ? (
139
- <NamespaceUnsupportedItem namespace={namespace} />
140
- ) : (
141
- <NamespaceListItem
142
- value={selectedNamespaces.includes(namespace.value)}
143
- namespace={namespace}
144
- type={singleNamespace ? 'radio' : 'checkbox'}
145
- onClick={() => onSelect(namespace.value)}
146
- />
147
- )}
148
- {index !== array.length - 1 && <Divider size={10} />}
149
- </React.Fragment>
150
- )
151
- )}
147
+ {needsNamespace?.data.map((namespace, index, array) => (
148
+ <React.Fragment key={namespace.id}>
149
+ {namespace.unsupported ? (
150
+ <NamespaceUnsupportedItem namespace={namespace} />
151
+ ) : (
152
+ <NamespaceListItem
153
+ value={selectedNamespaces.includes(namespace.value)}
154
+ namespace={namespace}
155
+ type={singleNamespace ? 'radio' : 'checkbox'}
156
+ onClick={() => onSelect(namespace.value)}
157
+ />
158
+ )}
159
+ {index !== array.length - 1 && <Divider size={10} />}
160
+ </React.Fragment>
161
+ ))}
152
162
  </>
153
163
  )}
154
164
  </NamespaceList>
@@ -15,7 +15,7 @@ const SUPPORTED_CHAINS_MAX_DISPLAYED_NUMBER = 3;
15
15
  export function SupportedChainsList(props: PropTypes) {
16
16
  const { chains } = props;
17
17
  return (
18
- <SupportedChainsContainer>
18
+ <SupportedChainsContainer id="widget-supported-chains-container">
19
19
  {chains
20
20
  .slice(0, SUPPORTED_CHAINS_MAX_DISPLAYED_NUMBER)
21
21
  .map((chain, index) => (
@@ -1,5 +1,5 @@
1
- import type { Chain } from '@rango-dev/wallets-core/dist/namespaces/common/types';
1
+ import type { BlockchainMeta } from 'rango-types';
2
2
 
3
3
  export type PropTypes = {
4
- chains: Chain[];
4
+ chains: BlockchainMeta[];
5
5
  };
@@ -15,6 +15,7 @@ export function ActivateTabModal(props: PropTypes) {
15
15
  open={open}
16
16
  dismissible
17
17
  onClose={onClose}
18
+ id="widget-active-tab-modal"
18
19
  container={getContainer()}>
19
20
  <MessageBox
20
21
  title={i18n.t('Activate current tab')}
@@ -47,7 +47,7 @@ export function ExpandedQuotes(props: PropTypes) {
47
47
  return (
48
48
  <Container
49
49
  expandMode={config?.variant === 'full-expanded' ? 'full' : 'default'}
50
- className={`${containerClass} ${LayoutContainer()}`}
50
+ className={`${containerClass} ${LayoutContainer()} widget-expanded-quotes-container`}
51
51
  id={WIDGET_UI_ID.EXPANDED_BOX_ID}>
52
52
  <Header
53
53
  title={i18n.t('Routes')}
@@ -78,6 +78,7 @@ export function Inputs(props: PropTypes) {
78
78
  <FromContainer>
79
79
  <SwapInput
80
80
  label={i18n.t('From')}
81
+ id="widget-swap-from"
81
82
  mode="From"
82
83
  onInputChange={setInputAmount}
83
84
  onInputBlur={sanitizeInputAmount}
@@ -133,6 +134,7 @@ export function Inputs(props: PropTypes) {
133
134
  sharpBottomStyle={!isExpandable && (!!selectedQuote || fetchingQuote)}
134
135
  label={i18n.t('To')}
135
136
  mode="To"
137
+ id="widget-swap-to-input"
136
138
  fetchingQuote={fetchingQuote}
137
139
  chain={{
138
140
  displayName: toBlockchain?.displayName || '',
@@ -23,6 +23,7 @@ export function QuoteInfo(props: PropTypes) {
23
23
  onClick,
24
24
  showModalFee,
25
25
  selected,
26
+ id,
26
27
  onClickAllRoutes,
27
28
  fullExpandedMode = false,
28
29
  container,
@@ -50,7 +51,7 @@ export function QuoteInfo(props: PropTypes) {
50
51
  }
51
52
 
52
53
  return showQuote ? (
53
- <QuoteContainer onClick={() => onClick?.(quote)}>
54
+ <QuoteContainer onClick={() => onClick?.(quote)} id={id}>
54
55
  <Quote
55
56
  quote={quote}
56
57
  error={error}
@@ -9,6 +9,7 @@ export type PropTypes = {
9
9
  tagHidden?: boolean;
10
10
  error: QuoteError | null;
11
11
  warning: QuoteWarning | null;
12
+ id: string;
12
13
  autoScrollOnExpanding?: boolean;
13
14
  expanded?: boolean;
14
15
  onClickAllRoutes?: () => void;
@@ -73,6 +73,7 @@ const themesList = [
73
73
  const getThemeIcon = (theme: ThemeMode) => {
74
74
  const iconProps: SvgIconProps = { color: 'gray', size: 16 };
75
75
 
76
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
76
77
  switch (theme) {
77
78
  case 'auto':
78
79
  return <AutoThemeIcon {...iconProps} />;
@@ -131,6 +132,7 @@ export function SettingsLists() {
131
132
  ).length;
132
133
 
133
134
  const handleSwapperEndItem = (totalSelected: number, total: number) => {
135
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
134
136
  switch (fetchStatus) {
135
137
  case 'loading':
136
138
  return <Skeleton variant="text" size="medium" width={50} />;
@@ -230,7 +232,7 @@ export function SettingsLists() {
230
232
  const infiniteApprovalItem = {
231
233
  id: 'widget-setting-infinite-approval-item-btn',
232
234
  title: (
233
- <>
235
+ <React.Fragment>
234
236
  <Typography variant="title" size="xmedium">
235
237
  {i18n.t('Infinite approval')}
236
238
  </Typography>
@@ -251,7 +253,7 @@ export function SettingsLists() {
251
253
  }>
252
254
  <InfoIcon color="gray" />
253
255
  </Tooltip>
254
- </>
256
+ </React.Fragment>
255
257
  ),
256
258
  start: <InfinityIcon color="gray" size={16} />,
257
259
  end: <Switch checked={infiniteApprove} />,
@@ -272,6 +274,7 @@ export function SettingsLists() {
272
274
  container={getContainer()}
273
275
  items={themesList}
274
276
  value={theme}
277
+ className="widget-setting-theme-item-tabs-container"
275
278
  onChange={(item) => setTheme(item.id as ThemeMode)}
276
279
  type="primary"
277
280
  borderRadius="small"
@@ -298,7 +301,14 @@ export function SettingsLists() {
298
301
 
299
302
  return (
300
303
  <List
301
- type={<ListItemButton hasDivider id="_" onClick={() => console.log()} />}
304
+ type={
305
+ <ListItemButton
306
+ className="widget-settings-list-item-btn"
307
+ hasDivider
308
+ id="_"
309
+ onClick={() => console.log()}
310
+ />
311
+ }
302
312
  items={settingItems}
303
313
  />
304
314
  );
@@ -97,25 +97,22 @@ export function useStatefulConnect(): UseStatefulConnect {
97
97
 
98
98
  // Legacy and hub have different structure to handle each situation.
99
99
  const isHub = !!wallet.isHub;
100
- const detachedInstances = wallet.properties?.find(
101
- (item) => item.name === 'detached'
102
- )?.value;
100
+ const needsNamespace = isHub
101
+ ? wallet.properties?.find((item) => item.name === 'namespaces')?.value
102
+ : wallet.needsNamespace;
103
+
104
+ const needsDerivationPath = isHub
105
+ ? wallet.properties?.find((item) => item.name === 'derivationPath')
106
+ ?.value
107
+ : wallet.needsDerivationPath;
103
108
 
104
109
  // 1. Target wallet does not contain any namespaces
105
- if (
106
- (isHub && !detachedInstances?.length) ||
107
- (!isHub && !wallet.needsNamespace)
108
- ) {
110
+ if (!needsNamespace?.data?.length) {
109
111
  return await runConnect(wallet.type, undefined, options);
110
112
  }
111
113
 
112
114
  // 2. Target wallet contains more than one namespace
113
- if (
114
- (isHub && detachedInstances?.length && detachedInstances.length > 1) ||
115
- (!isHub &&
116
- wallet.needsNamespace?.data.length &&
117
- wallet.needsNamespace.data.length > 1)
118
- ) {
115
+ if (needsNamespace?.data.length && needsNamespace.data.length > 1) {
119
116
  dispatch({
120
117
  type: 'needsNamespace',
121
118
  payload: {
@@ -127,12 +124,9 @@ export function useStatefulConnect(): UseStatefulConnect {
127
124
  }
128
125
 
129
126
  // 3. Target wallet contains only one namespace
130
- if (
131
- (isHub && detachedInstances?.length === 1) ||
132
- (!isHub && wallet.needsNamespace?.data.length === 1)
133
- ) {
134
- if (wallet.needsNamespace && wallet.needsDerivationPath) {
135
- const namespace = wallet.needsNamespace.data[0];
127
+ if (needsNamespace?.data.length === 1) {
128
+ if (needsDerivationPath) {
129
+ const namespace = needsNamespace.data[0];
136
130
 
137
131
  dispatch({
138
132
  type: 'needsDerivationPath',
@@ -146,7 +140,7 @@ export function useStatefulConnect(): UseStatefulConnect {
146
140
  }
147
141
  return await runConnect(
148
142
  wallet.type,
149
- wallet.needsNamespace?.data.map((namespace) => ({
143
+ needsNamespace?.data?.map((namespace) => ({
150
144
  namespace: namespace.value,
151
145
  })),
152
146
  options
@@ -182,11 +176,19 @@ export function useStatefulConnect(): UseStatefulConnect {
182
176
  };
183
177
 
184
178
  const handleNamespace = async (
185
- wallet: WalletInfoWithExtra,
179
+ wallet: ExtendedModalWalletInfo,
186
180
  selectedNamespaces: Namespace[]
187
181
  ): Promise<Result> => {
188
- const isSingleNamespace = wallet.needsNamespace?.selection === 'single';
189
- const needsDerivationPath = wallet.needsDerivationPath;
182
+ const isHub = !!wallet.isHub;
183
+ const needsNamespace = isHub
184
+ ? wallet.properties?.find((item) => item.name === 'namespaces')?.value
185
+ : wallet.needsNamespace;
186
+
187
+ const needsDerivationPath = isHub
188
+ ? wallet.properties?.find((item) => item.name === 'derivationPath')?.value
189
+ : wallet.needsDerivationPath;
190
+
191
+ const isSingleNamespace = needsNamespace?.selection === 'single';
190
192
  const firstSelectedNamespace = selectedNamespaces[0];
191
193
 
192
194
  if (!firstSelectedNamespace) {
@@ -93,6 +93,7 @@ export function AddCustomTokenPage() {
93
93
  <Divider size={10} />
94
94
  <TextField
95
95
  fullWidth
96
+ id="widget-add-custom-token-token-address-input"
96
97
  disabled={!blockchain}
97
98
  variant="contained"
98
99
  placeholder={i18n.t('Enter token address')}
@@ -107,7 +108,12 @@ export function AddCustomTokenPage() {
107
108
  {!isValidAddress && !!address && (
108
109
  <>
109
110
  <Divider size={4} />
110
- <Alert type="error" variant="alarm" title="Invalid Address" />
111
+ <Alert
112
+ id="widget-add-custom-token-invalid-address-alert"
113
+ type="error"
114
+ variant="alarm"
115
+ title="Invalid Address"
116
+ />
111
117
  </>
112
118
  )}
113
119
  </div>
@@ -199,7 +199,14 @@ export function ConfirmSwapPage() {
199
199
  const quoteError = confirmSwapResult.error;
200
200
  const alerts = [];
201
201
  if (dbErrorMessage) {
202
- alerts.push(<Alert type="error" variant="alarm" title={dbErrorMessage} />);
202
+ alerts.push(
203
+ <Alert
204
+ id="widget-confirm-swap-db-error-alert"
205
+ type="error"
206
+ variant="alarm"
207
+ title={dbErrorMessage}
208
+ />
209
+ );
203
210
  }
204
211
 
205
212
  if (quoteWarning || quoteError) {
@@ -304,6 +311,7 @@ export function ConfirmSwapPage() {
304
311
  <QuoteInfo
305
312
  quote={selectedQuote}
306
313
  type="swap-preview"
314
+ id="widget-confirm-swap-quote-container"
307
315
  expanded
308
316
  tagHidden
309
317
  error={confirmSwapResult.error}
@@ -94,6 +94,7 @@ export function CustomTokensPage() {
94
94
  {!!customTokens.length ? (
95
95
  <>
96
96
  <SearchInput
97
+ id="widget-custom-tokens-search-token-input"
97
98
  value={searchedFor}
98
99
  setValue={setSearchedFor}
99
100
  fullWidth
@@ -152,6 +153,7 @@ export function CustomTokensPage() {
152
153
  </Content>
153
154
  <WatermarkedModal
154
155
  open={isDeleteModalOpen}
156
+ id="widget-custom-tokens-delete-modal"
155
157
  dismissible
156
158
  onClose={() => setIsDeleteModalOpen(false)}
157
159
  container={getContainer()}>
@@ -159,6 +159,7 @@ export function HistoryPage() {
159
159
  fullWidth
160
160
  variant="contained"
161
161
  placeholder={i18n.t('Search Transaction')}
162
+ id="widget-history-search-transaction-input"
162
163
  autoFocus
163
164
  onChange={handleSearch}
164
165
  style={{ height: 36 }}
@@ -211,6 +212,7 @@ export function HistoryPage() {
211
212
  <WatermarkedModal
212
213
  open={openClearModal}
213
214
  onClose={onCloseModal}
215
+ id="widget-history-clear-modal"
214
216
  container={getContainer()}>
215
217
  <Divider size={20} />
216
218
  <MessageBox
@@ -217,6 +217,7 @@ export function Home() {
217
217
  quote={selectedQuote}
218
218
  loading={fetchingQuote}
219
219
  error={quoteError}
220
+ id="widget-home-expandable-quote-container"
220
221
  tagHidden={false}
221
222
  warning={currentQuoteWarning}
222
223
  type="basic"