@rango-dev/widget-embedded 0.63.1-next.1 → 0.63.1-next.11

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 (138) hide show
  1. package/dist/QueueManager.d.ts.map +1 -1
  2. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -1
  3. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  4. package/dist/components/CustomDestination/CustomDestination.styles.d.ts +4 -4
  5. package/dist/components/CustomDestination/CustomDestination.styles.d.ts.map +1 -1
  6. package/dist/components/CustomTokenModal/CustomTokenModal.styles.d.ts +169 -169
  7. package/dist/components/CustomTokenModal/CustomTokenModal.styles.d.ts.map +1 -1
  8. package/dist/components/FilterSelector/FilterSelector.style.d.ts +1 -1
  9. package/dist/components/FilterSelector/FilterSelector.style.d.ts.map +1 -1
  10. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +1 -1
  11. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts.map +1 -1
  12. package/dist/components/NamespaceItem/NamespaceItem.styles.d.ts +1 -1
  13. package/dist/components/NamespaceItem/NamespaceItem.styles.d.ts.map +1 -1
  14. package/dist/components/NamespaceItem/NamespaceItem.types.d.ts +3 -3
  15. package/dist/components/NamespaceItem/NamespaceItem.types.d.ts.map +1 -1
  16. package/dist/components/Quote/Quote.styles.d.ts +171 -171
  17. package/dist/components/Quote/Quote.styles.d.ts.map +1 -1
  18. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts +169 -169
  19. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
  20. package/dist/components/RefreshModal/RefreshModal.styles.d.ts +168 -168
  21. package/dist/components/RefreshModal/RefreshModal.styles.d.ts.map +1 -1
  22. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  23. package/dist/components/SwapDetails/SwapDetails.styles.d.ts +1 -1
  24. package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
  25. package/dist/components/SwapDetailsModal/SwapDetailsModal.ConnectWallet.d.ts.map +1 -1
  26. package/dist/components/SwapDetailsModal/SwapDetailsModal.InstallWallet.d.ts.map +1 -1
  27. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts +3 -3
  28. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts.map +1 -1
  29. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts +1 -1
  30. package/dist/components/SwapMetrics/SwapMetrics.styles.d.ts.map +1 -1
  31. package/dist/components/TokenList/TokenList.styles.d.ts +2 -2
  32. package/dist/components/TokenList/TokenList.styles.d.ts.map +1 -1
  33. package/dist/components/WalletStatefulConnect/DerivationPath.d.ts.map +1 -1
  34. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts +7 -3
  35. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.d.ts.map +1 -1
  36. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.test.d.ts +2 -0
  37. package/dist/components/WalletStatefulConnect/DerivationPath.helpers.test.d.ts.map +1 -0
  38. package/dist/components/WalletStatefulConnect/DerivationPath.styles.d.ts +169 -169
  39. package/dist/components/WalletStatefulConnect/DerivationPath.styles.d.ts.map +1 -1
  40. package/dist/components/WalletStatefulConnect/NamespaceDetachedItem.d.ts.map +1 -1
  41. package/dist/components/WalletStatefulConnect/Namespaces.d.ts.map +1 -1
  42. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts +168 -168
  43. package/dist/components/WalletStatefulConnect/Namespaces.styles.d.ts.map +1 -1
  44. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts +3 -3
  45. package/dist/components/WalletStatefulConnect/Namespaces.types.d.ts.map +1 -1
  46. package/dist/constants/errors.d.ts +1 -0
  47. package/dist/constants/errors.d.ts.map +1 -1
  48. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  49. package/dist/containers/Wallets/Wallets.helpers.d.ts +2 -2
  50. package/dist/containers/Wallets/Wallets.helpers.d.ts.map +1 -1
  51. package/dist/containers/Wallets/Wallets.types.d.ts +4 -4
  52. package/dist/containers/Wallets/Wallets.types.d.ts.map +1 -1
  53. package/dist/containers/Wallets/useUpdates.d.ts +1 -1
  54. package/dist/containers/Wallets/useUpdates.d.ts.map +1 -1
  55. package/dist/containers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  56. package/dist/containers/WidgetProvider/WidgetProvider.helpers.d.ts +5 -0
  57. package/dist/containers/WidgetProvider/WidgetProvider.helpers.d.ts.map +1 -0
  58. package/dist/containers/WidgetProvider/WidgetProvider.types.d.ts +1 -1
  59. package/dist/containers/WidgetProvider/WidgetProvider.types.d.ts.map +1 -1
  60. package/dist/hooks/useStatefulConnect/useStatefulConnect.d.ts.map +1 -1
  61. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts +5 -4
  62. package/dist/hooks/useStatefulConnect/useStatefulConnect.types.d.ts.map +1 -1
  63. package/dist/hooks/useWalletList.d.ts.map +1 -1
  64. package/dist/hooks/useWalletProviders/useWalletProviders.d.ts +2 -2
  65. package/dist/hooks/useWalletProviders/useWalletProviders.d.ts.map +1 -1
  66. package/dist/hooks/useWalletProviders/useWalletProviders.helpers.d.ts +2 -3
  67. package/dist/hooks/useWalletProviders/useWalletProviders.helpers.d.ts.map +1 -1
  68. package/dist/index.d.ts +10 -7
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +3 -2
  71. package/dist/index.js.map +4 -4
  72. package/dist/store/AppStore.d.ts +2 -2
  73. package/dist/store/AppStore.d.ts.map +1 -1
  74. package/dist/store/app.d.ts +2 -2
  75. package/dist/store/app.d.ts.map +1 -1
  76. package/dist/store/slices/config.d.ts +5 -5
  77. package/dist/store/slices/config.d.ts.map +1 -1
  78. package/dist/test-utils/fixtures.d.ts +2 -2
  79. package/dist/test-utils/fixtures.d.ts.map +1 -1
  80. package/dist/types/config.d.ts +25 -4
  81. package/dist/types/config.d.ts.map +1 -1
  82. package/dist/types/wallets.d.ts +1 -1
  83. package/dist/types/wallets.d.ts.map +1 -1
  84. package/dist/utils/common.d.ts +1 -0
  85. package/dist/utils/common.d.ts.map +1 -1
  86. package/dist/utils/errors.d.ts +14 -0
  87. package/dist/utils/errors.d.ts.map +1 -0
  88. package/dist/utils/errors.test.d.ts +2 -0
  89. package/dist/utils/errors.test.d.ts.map +1 -0
  90. package/dist/utils/providers.d.ts +3 -6
  91. package/dist/utils/providers.d.ts.map +1 -1
  92. package/dist/utils/swap.d.ts +1 -1
  93. package/dist/utils/swap.d.ts.map +1 -1
  94. package/dist/utils/wallets.d.ts +2 -1
  95. package/dist/utils/wallets.d.ts.map +1 -1
  96. package/package.json +8 -9
  97. package/src/QueueManager.tsx +10 -7
  98. package/src/components/NamespaceItem/NamespaceItem.tsx +1 -1
  99. package/src/components/NamespaceItem/NamespaceItem.types.ts +3 -3
  100. package/src/components/SwapDetails/SwapDetails.tsx +4 -1
  101. package/src/components/SwapDetailsModal/SwapDetailsModal.ConnectWallet.tsx +7 -11
  102. package/src/components/SwapDetailsModal/SwapDetailsModal.InstallWallet.tsx +8 -2
  103. package/src/components/SwapDetailsModal/SwapDetailsModal.types.ts +3 -3
  104. package/src/components/TokenList/LoadingTokenList.tsx +2 -2
  105. package/src/components/WalletStatefulConnect/DerivationPath.helpers.test.ts +98 -0
  106. package/src/components/WalletStatefulConnect/DerivationPath.helpers.ts +14 -10
  107. package/src/components/WalletStatefulConnect/DerivationPath.tsx +14 -7
  108. package/src/components/WalletStatefulConnect/Detached.tsx +2 -2
  109. package/src/components/WalletStatefulConnect/NamespaceDetachedItem.tsx +2 -1
  110. package/src/components/WalletStatefulConnect/Namespaces.tsx +3 -8
  111. package/src/components/WalletStatefulConnect/Namespaces.types.tsx +3 -3
  112. package/src/constants/errors.ts +3 -0
  113. package/src/containers/Wallets/Wallets.helpers.ts +4 -4
  114. package/src/containers/Wallets/Wallets.tsx +6 -3
  115. package/src/containers/Wallets/Wallets.types.ts +4 -7
  116. package/src/containers/Wallets/useUpdates.ts +4 -119
  117. package/src/containers/WidgetProvider/WidgetProvider.helpers.ts +10 -0
  118. package/src/containers/WidgetProvider/WidgetProvider.tsx +12 -1
  119. package/src/containers/WidgetProvider/WidgetProvider.types.ts +1 -1
  120. package/src/hooks/useStatefulConnect/useStatefulConnect.ts +28 -26
  121. package/src/hooks/useStatefulConnect/useStatefulConnect.types.ts +6 -3
  122. package/src/hooks/useWalletList.ts +10 -7
  123. package/src/hooks/useWalletProviders/useWalletProviders.helpers.ts +3 -10
  124. package/src/hooks/useWalletProviders/useWalletProviders.ts +2 -2
  125. package/src/index.ts +10 -11
  126. package/src/store/AppStore.tsx +4 -2
  127. package/src/store/app.ts +7 -2
  128. package/src/store/slices/config.ts +39 -12
  129. package/src/store/slices/data.test.ts +2 -2
  130. package/src/test-utils/fixtures.ts +6 -2
  131. package/src/types/config.ts +31 -4
  132. package/src/types/wallets.ts +1 -1
  133. package/src/utils/common.ts +6 -0
  134. package/src/utils/errors.test.ts +78 -0
  135. package/src/utils/errors.ts +69 -0
  136. package/src/utils/providers.ts +16 -50
  137. package/src/utils/swap.ts +8 -1
  138. package/src/utils/wallets.ts +12 -15
@@ -1,13 +1,17 @@
1
- import type { HandleConnectOptions, Result } from './useStatefulConnect.types';
1
+ import type {
2
+ HandleConnectOptions,
3
+ NamespaceData,
4
+ Result,
5
+ } from './useStatefulConnect.types';
2
6
  import type { WalletInfoWithExtra } from '../../types';
3
7
  import type { Namespace } from '@hub3js/namespaces';
4
- import type { NamespaceData } from '@rango-dev/wallets-shared';
5
8
 
6
9
  import { WalletState } from '@rango-dev/ui';
7
10
  import { useWallets } from '@rango-dev/wallets-react';
8
11
  import { useReducer } from 'react';
9
12
 
10
13
  import { isOnDetached } from '../../components/StatefulConnectModal';
14
+ import { tryRefineErrorMessage } from '../../utils/errors';
11
15
  import { type ExtendedModalWalletInfo } from '../../utils/wallets';
12
16
 
13
17
  import {
@@ -75,9 +79,12 @@ export function useStatefulConnect(): UseStatefulConnect {
75
79
  return { status: ResultStatus.Connected };
76
80
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
81
  } catch (e: any) {
78
- const message = e?.message
79
- ? `Error: ${e.message}`
80
- : 'An unknown error happened during connecting wallet.';
82
+ const message = tryRefineErrorMessage(
83
+ e,
84
+ e?.message
85
+ ? `Error: ${e.message}`
86
+ : 'An unknown error happened during connecting wallet.'
87
+ );
81
88
 
82
89
  if (options?.disconnectOnError) {
83
90
  try {
@@ -110,16 +117,13 @@ export function useStatefulConnect(): UseStatefulConnect {
110
117
  * 3. Target wallet contains only one namespace, in this situation we should check if that namespace needs derivation path and based on that, try to connect to the related provider or display derivation path modal.
111
118
  */
112
119
 
113
- // Legacy and hub have different structure to handle each situation.
114
- const isHub = !!wallet.isHub;
115
- const needsNamespace = isHub
116
- ? wallet.properties?.find((item) => item.name === 'namespaces')?.value
117
- : wallet.needsNamespace;
120
+ const needsNamespace = wallet.properties?.find(
121
+ (item) => item.name === 'namespaces'
122
+ )?.value;
118
123
 
119
- const needsDerivationPath = isHub
120
- ? wallet.properties?.find((item) => item.name === 'derivationPath')
121
- ?.value
122
- : wallet.needsDerivationPath;
124
+ const needsDerivationPath = wallet.properties?.find(
125
+ (item) => item.name === 'derivationPath'
126
+ )?.value;
123
127
 
124
128
  // Forced namespaces are used to bypass namespace selection flow.
125
129
  if (forceConnectToNamespaces) {
@@ -209,7 +213,7 @@ export function useStatefulConnect(): UseStatefulConnect {
209
213
  * and forced namespaces are not enabled,
210
214
  * we should display detached modal
211
215
  */
212
- if (!!wallet.isHub && !options?.forceConnectToNamespaces) {
216
+ if (!options?.forceConnectToNamespaces) {
213
217
  const needsNamespace = wallet.properties?.find(
214
218
  (item) => item.name === 'namespaces'
215
219
  )?.value;
@@ -237,14 +241,13 @@ export function useStatefulConnect(): UseStatefulConnect {
237
241
  wallet: ExtendedModalWalletInfo,
238
242
  selectedNamespaces: Namespace[]
239
243
  ): Promise<Result> => {
240
- const isHub = !!wallet.isHub;
241
- const needsNamespace = isHub
242
- ? wallet.properties?.find((item) => item.name === 'namespaces')?.value
243
- : wallet.needsNamespace;
244
+ const needsNamespace = wallet.properties?.find(
245
+ (item) => item.name === 'namespaces'
246
+ )?.value;
244
247
 
245
- const needsDerivationPath = isHub
246
- ? wallet.properties?.find((item) => item.name === 'derivationPath')?.value
247
- : wallet.needsDerivationPath;
248
+ const needsDerivationPath = wallet.properties?.find(
249
+ (item) => item.name === 'derivationPath'
250
+ )?.value;
248
251
 
249
252
  const isSingleNamespace = needsNamespace?.selection === 'single';
250
253
  const firstSelectedNamespace = selectedNamespaces[0];
@@ -320,10 +323,9 @@ export function useStatefulConnect(): UseStatefulConnect {
320
323
  const selectedNamespace = connectState.derivationPath.namespace;
321
324
  const namespaces = [{ namespace: selectedNamespace, derivationPath }];
322
325
 
323
- const isHub = !!wallet.isHub;
324
- const needsNamespace = isHub
325
- ? wallet.properties?.find((item) => item.name === 'namespaces')?.value
326
- : wallet.needsNamespace;
326
+ const needsNamespace = wallet.properties?.find(
327
+ (item) => item.name === 'namespaces'
328
+ )?.value;
327
329
 
328
330
  const namespaceIsAvailable =
329
331
  !!needsNamespace?.data && needsNamespace.data.length > 1;
@@ -1,6 +1,11 @@
1
1
  import type { ExtendedModalWalletInfo } from '../../utils/wallets';
2
2
  import type { Namespace } from '@hub3js/namespaces';
3
3
 
4
+ export interface NamespaceData {
5
+ namespace: Namespace;
6
+ derivationPath?: string;
7
+ }
8
+
4
9
  export interface HandleConnectOptions {
5
10
  // To have a switch between connect and disconnect when user is clicking on a button, this option can be helpful.
6
11
  forceConnectToNamespaces?: Namespace[];
@@ -15,9 +20,7 @@ export interface NeedsNamespacesState {
15
20
 
16
21
  export interface DetachedPayload {
17
22
  targetWallet: ExtendedModalWalletInfo;
18
- selectedNamespaces:
19
- | { namespace: Namespace; derivationPath?: string }[]
20
- | null;
23
+ selectedNamespaces: NamespaceData[] | null;
21
24
  derivationPath?: string;
22
25
  }
23
26
 
@@ -1,12 +1,13 @@
1
1
  import type { ExtendedModalWalletInfo } from '../utils/wallets';
2
2
  import type { WalletInfo } from '@rango-dev/ui';
3
3
 
4
+ import { WalletTypes } from '@rango-dev/provider-all';
4
5
  import { WalletState } from '@rango-dev/ui';
5
6
  import { useWallets } from '@rango-dev/wallets-react';
6
- import { detectMobileScreens, WalletTypes } from '@rango-dev/wallets-shared';
7
7
  import { useCallback, useEffect } from 'react';
8
8
 
9
9
  import { useAppStore } from '../store/AppStore';
10
+ import { detectMobileScreens } from '../utils/common';
10
11
  import { emitWalletDetected } from '../utils/events';
11
12
  import { configWalletsToWalletName } from '../utils/providers';
12
13
  import {
@@ -37,6 +38,12 @@ const NON_INJECTED_WALLET_TYPES = new Set<string>([
37
38
  WalletTypes.DEFAULT,
38
39
  ]);
39
40
 
41
+ const DEFAULT_EVM_WALLETS = new Set<string>([
42
+ WalletTypes.DEFAULT,
43
+ WalletTypes.WALLET_CONNECT_2,
44
+ WalletTypes.LEDGER,
45
+ ]);
46
+
40
47
  interface Params {
41
48
  chain?: string;
42
49
  }
@@ -89,7 +96,7 @@ export function useWalletList(params?: Params): API {
89
96
  if (isDetected && !detectedWalletsReported.has(wallet.type)) {
90
97
  detectedWalletsReported.add(wallet.type);
91
98
  emitWalletDetected({
92
- walletName: wallet.title,
99
+ walletName: wallet.type,
93
100
  });
94
101
  }
95
102
  });
@@ -131,11 +138,7 @@ export function useWalletList(params?: Params): API {
131
138
  const isEvmWalletInstalledExceptDefault = wallets.filter(
132
139
  (wallet) =>
133
140
  wallet.state != WalletState.NOT_INSTALLED &&
134
- ![
135
- WalletTypes.DEFAULT,
136
- WalletTypes.WALLET_CONNECT_2,
137
- WalletTypes.LEDGER,
138
- ].includes(wallet.type as WalletTypes) &&
141
+ !DEFAULT_EVM_WALLETS.has(wallet.type) &&
139
142
  getWalletInfo(wallet.type).supportedChains.filter(
140
143
  (blockchain) => blockchain.type == 'EVM'
141
144
  ).length > 0
@@ -1,19 +1,12 @@
1
- import type { ProviderInterface } from '@rango-dev/wallets-react';
1
+ import type { Provider } from '@hub3js/core';
2
2
 
3
- import { Provider } from '@hub3js/core';
4
-
5
- export function hashProviders(
6
- providers: (string | ProviderInterface | Provider)[]
7
- ): string {
3
+ export function hashProviders(providers: (string | Provider)[]): string {
8
4
  return providers
9
5
  .map((provider) => {
10
6
  if (typeof provider === 'string') {
11
7
  return provider;
12
8
  }
13
- if (provider instanceof Provider) {
14
- return provider.id;
15
- }
16
- return provider.config.type;
9
+ return provider.id;
17
10
  })
18
11
  .join('-');
19
12
  }
@@ -1,4 +1,4 @@
1
- import type { WidgetConfig } from '../../types';
1
+ import type { WidgetConfigWithoutLegacyProviders } from '../../types';
2
2
  import type { ProvidersOptions } from '../../utils/providers';
3
3
 
4
4
  import { useEffect } from 'react';
@@ -8,7 +8,7 @@ import { useAppStore } from '../../store/AppStore';
8
8
  import { hashProviders } from './useWalletProviders.helpers';
9
9
 
10
10
  export function useWalletProviders(
11
- configWallets: WidgetConfig['wallets'],
11
+ configWallets: WidgetConfigWithoutLegacyProviders['wallets'],
12
12
  options?: ProvidersOptions
13
13
  ) {
14
14
  const { clearConnectedWallet, getAvailableProviders, buildAndSetProviders } =
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ import type {
14
14
  WidgetTheme,
15
15
  WidgetVariant,
16
16
  } from './types';
17
+ import type { WalletType } from '@hub3js/core';
17
18
  import type {
18
19
  PendingSwapWithQueueID,
19
20
  Route,
@@ -36,16 +37,14 @@ import type {
36
37
  StepTxExecutionUpdatedEvent,
37
38
  } from '@rango-dev/queue-manager-rango-preset';
38
39
  import type {
39
- LegacyEventHandler as HandleWalletsUpdate,
40
- LegacyProviderInterface as ProviderInterface,
41
- } from '@rango-dev/wallets-core/legacy';
42
- import type {
40
+ EventHandler as HandleWalletsUpdate,
41
+ ProviderInterface,
43
42
  WalletInfo,
44
43
  WalletState,
45
- WalletType,
46
- } from '@rango-dev/wallets-shared';
44
+ } from '@rango-dev/wallets-react';
47
45
  import type { PendingSwap, PendingSwapStep } from 'rango-types';
48
46
 
47
+ import { Networks, readAccountAddress } from '@rango-dev/internal-blockchains';
49
48
  import {
50
49
  EventSeverity,
51
50
  RouteEventType,
@@ -53,9 +52,7 @@ import {
53
52
  StepExecutionBlockedEventStatus,
54
53
  StepExecutionEventStatus,
55
54
  } from '@rango-dev/queue-manager-rango-preset';
56
- import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy';
57
55
  import { useWallets, Events as WalletEvents } from '@rango-dev/wallets-react';
58
- import { Networks, WalletTypes } from '@rango-dev/wallets-shared';
59
56
  import { PendingSwapNetworkStatus } from 'rango-types';
60
57
 
61
58
  import {
@@ -87,7 +84,7 @@ import {
87
84
  WalletEventTypes,
88
85
  WidgetEvents,
89
86
  } from './types';
90
- import { pickProviderVersionWithFallbackToLegacy } from './utils/providers';
87
+ import { pickProviderVersion } from './utils/providers';
91
88
  import { customizedThemeTokens } from './utils/ui';
92
89
 
93
90
  export const StatefulConnect = {
@@ -105,6 +102,9 @@ export type {
105
102
  WidgetTheme,
106
103
  WidgetColors,
107
104
  WidgetColorsKeys,
105
+ /**
106
+ * @deprecated Pass a hub `Provider` instead. This type will be removed in future versions.
107
+ */
108
108
  ProviderInterface,
109
109
  BlockchainAndTokenConfig,
110
110
  WidgetProps,
@@ -183,10 +183,9 @@ export type {
183
183
  // Internal function and enum exports for Rango
184
184
  export {
185
185
  readAccountAddress,
186
- pickProviderVersionWithFallbackToLegacy,
186
+ pickProviderVersion,
187
187
  Networks,
188
188
  WalletEvents,
189
- WalletTypes,
190
189
  PendingSwapNetworkStatus,
191
190
  EventSeverity,
192
191
  };
@@ -1,4 +1,4 @@
1
- import type { WidgetConfig } from '../types';
1
+ import type { WidgetConfigWithoutLegacyProviders } from '../types';
2
2
  import type { PropsWithChildren } from 'react';
3
3
 
4
4
  import React, { createContext, useContext, useEffect, useRef } from 'react';
@@ -6,7 +6,9 @@ import React, { createContext, useContext, useEffect, useRef } from 'react';
6
6
  import { createAppStore } from './app';
7
7
 
8
8
  type AppStore = ReturnType<typeof createAppStore>;
9
- type AppStoreProviderProps = PropsWithChildren<{ config?: WidgetConfig }>;
9
+ type AppStoreProviderProps = PropsWithChildren<{
10
+ config?: WidgetConfigWithoutLegacyProviders;
11
+ }>;
10
12
 
11
13
  export const AppStoreContext = createContext<AppStore | null>(null);
12
14
 
package/src/store/app.ts CHANGED
@@ -1,4 +1,7 @@
1
- import type { WidgetConfig } from '../types';
1
+ import type {
2
+ WidgetConfig,
3
+ WidgetConfigWithoutLegacyProviders,
4
+ } from '../types';
2
5
  import type { AppStoreState } from './slices/types';
3
6
  import type { StateCreator } from 'zustand';
4
7
 
@@ -21,7 +24,9 @@ export type StateCreatorWithInitialData<
21
24
 
22
25
  export type { AppStoreState };
23
26
 
24
- export function createAppStore(initialData?: WidgetConfig) {
27
+ export function createAppStore(
28
+ initialData?: WidgetConfigWithoutLegacyProviders
29
+ ) {
25
30
  return create<AppStoreState>()(
26
31
  persist(
27
32
  (...a) => ({
@@ -1,13 +1,20 @@
1
1
  import type { DataSlice } from './data';
2
2
  import type { SettingsSlice } from './settings';
3
- import type { WidgetConfig } from '../../types';
3
+ import type {
4
+ WidgetConfig,
5
+ WidgetConfigWithoutLegacyProviders,
6
+ } from '../../types';
4
7
  import type { StateCreatorWithInitialData } from '../app';
5
8
  import type { VersionedProviders } from '@hub3js/core/utils';
6
9
 
7
- import { allProviders as getAllProviders } from '@rango-dev/provider-all';
10
+ import {
11
+ allProviders as getAllProviders,
12
+ WalletTypes,
13
+ } from '@rango-dev/provider-all';
8
14
 
9
15
  import { cacheService } from '../../services/cacheService';
10
16
  import {
17
+ configWalletsToWalletName,
11
18
  matchAndGenerateProviders,
12
19
  type ProvidersOptions,
13
20
  } from '../../utils/providers';
@@ -27,7 +34,7 @@ function makeProvidersOptionsFromConfig(
27
34
  return options;
28
35
  }
29
36
 
30
- export const DEFAULT_CONFIG: WidgetConfig = {
37
+ export const DEFAULT_CONFIG: WidgetConfigWithoutLegacyProviders = {
31
38
  apiKey: '',
32
39
  title: undefined,
33
40
  multiWallets: true,
@@ -62,13 +69,13 @@ const DEFAULT_CAMPAIGN_MODE: CampaignMode = {
62
69
 
63
70
  export interface ConfigSlice {
64
71
  // What user can set directly.
65
- config: WidgetConfig;
72
+ config: WidgetConfigWithoutLegacyProviders;
66
73
  campaignMode: CampaignMode;
67
74
  isInCampaignMode: () => boolean;
68
75
  getLiquiditySources: () => string[];
69
76
  getDisabledLiquiditySources: () => string[];
70
77
  excludeLiquiditySources: () => boolean;
71
- updateConfig: (config: WidgetConfig) => void;
78
+ updateConfig: (config: WidgetConfigWithoutLegacyProviders) => void;
72
79
  updateCampaignMode: <K extends keyof CampaignMode>(
73
80
  name: K,
74
81
  value: CampaignMode[K]
@@ -84,21 +91,40 @@ export interface ConfigSlice {
84
91
  getAvailableProviders: () => VersionedProviders[];
85
92
  }
86
93
 
87
- function generateProviders() {
94
+ function generateProviders(
95
+ config: WidgetConfigWithoutLegacyProviders
96
+ ): VersionedProviders[] {
88
97
  const allProviders = getAllProviders();
89
98
  const allBuiltProviders = allProviders.map((build) => build());
90
99
 
91
- return allBuiltProviders;
100
+ const providerNames = configWalletsToWalletName(allBuiltProviders);
101
+
102
+ const filteredProviders = allBuiltProviders.filter((_, index) => {
103
+ if (
104
+ providerNames[index] === WalletTypes.LEDGER_WALLET &&
105
+ (!config.ledgerWallet?.apiKey || !config.ledgerWallet?.dAppIdentifier)
106
+ ) {
107
+ return false;
108
+ }
109
+
110
+ return true;
111
+ });
112
+
113
+ return filteredProviders;
92
114
  }
93
115
 
94
116
  export const createConfigSlice: StateCreatorWithInitialData<
95
- WidgetConfig,
117
+ WidgetConfigWithoutLegacyProviders,
96
118
  ConfigSlice & SettingsSlice & DataSlice,
97
119
  ConfigSlice
98
120
  > = (initialData, set, get) => {
99
- const allBuiltProviders = generateProviders();
121
+ const config: WidgetConfigWithoutLegacyProviders = {
122
+ ...DEFAULT_CONFIG,
123
+ ...initialData,
124
+ };
125
+ const allBuiltProviders = generateProviders(config);
100
126
  return {
101
- config: { ...DEFAULT_CONFIG, ...initialData },
127
+ config,
102
128
  iframe: DEFAULT_IFRAME_CONFIGS,
103
129
  campaignMode: DEFAULT_CAMPAIGN_MODE,
104
130
  allProviders: allBuiltProviders,
@@ -126,7 +152,7 @@ export const createConfigSlice: StateCreatorWithInitialData<
126
152
  },
127
153
 
128
154
  // Actions
129
- updateConfig: (nextConfig: WidgetConfig) => {
155
+ updateConfig: (nextConfig: WidgetConfigWithoutLegacyProviders) => {
130
156
  const currentConfig = get().config;
131
157
  const {
132
158
  _tokensMapByTokenHash: tokensMapByTokenHash,
@@ -194,7 +220,8 @@ export const createConfigSlice: StateCreatorWithInitialData<
194
220
  },
195
221
 
196
222
  buildAndSetProviders: () => {
197
- const allBuiltProviders = generateProviders();
223
+ const { config } = get();
224
+ const allBuiltProviders = generateProviders(config);
198
225
 
199
226
  set({
200
227
  allProviders: allBuiltProviders,
@@ -1,4 +1,4 @@
1
- import type { WidgetConfig } from '../../types';
1
+ import type { WidgetConfigWithoutLegacyProviders } from '../../types';
2
2
  import type { AppStoreState } from '../app';
3
3
  import type { EvmBlockchainMeta, Token } from 'rango-sdk';
4
4
 
@@ -18,7 +18,7 @@ let appStoreState: AppStoreState;
18
18
  let customTokens: [Token, Token, Token];
19
19
  let rangoBlockchain: EvmBlockchainMeta;
20
20
 
21
- const DEFAULT_CONFIG: WidgetConfig = {
21
+ const DEFAULT_CONFIG: WidgetConfigWithoutLegacyProviders = {
22
22
  apiKey: '',
23
23
  walletConnectProjectId: 'e24844c5deb5193c1c14840a7af6a40b',
24
24
  title: undefined,
@@ -1,5 +1,9 @@
1
1
  import type { AppStoreState } from '../store/app';
2
- import type { Blockchain, TokenHash, WidgetConfig } from '../types';
2
+ import type {
3
+ Blockchain,
4
+ TokenHash,
5
+ WidgetConfigWithoutLegacyProviders,
6
+ } from '../types';
3
7
  import type { BlockchainMeta, EvmBlockchainMeta, Token } from 'rango-sdk';
4
8
 
5
9
  import { faker } from '@faker-js/faker';
@@ -216,7 +220,7 @@ export function createInitialAppStore() {
216
220
 
217
221
  export function updateAppStoreConfig(
218
222
  appStoreState: AppStoreState,
219
- config: Partial<WidgetConfig>
223
+ config: Partial<WidgetConfigWithoutLegacyProviders>
220
224
  ): AppStoreState {
221
225
  appStoreState.config = {
222
226
  ...appStoreState.config,
@@ -1,7 +1,6 @@
1
- import type { Provider } from '@hub3js/core';
1
+ import type { Provider, WalletType } from '@hub3js/core';
2
2
  import type { Language, theme } from '@rango-dev/ui';
3
- import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy';
4
- import type { WalletType } from '@rango-dev/wallets-shared';
3
+ import type { ProviderInterface } from '@rango-dev/wallets-react';
5
4
  import type { Asset } from 'rango-sdk';
6
5
  import type { ReactElement } from 'react';
7
6
 
@@ -186,6 +185,21 @@ export type TonConnectConfig = {
186
185
  manifestUrl?: string;
187
186
  };
188
187
 
188
+ /**
189
+ * Configuration for the Ledger wallet integration.
190
+ *
191
+ * @property {string} dAppIdentifier - Unique identifier of your dApp, registered with Ledger to authorize the integration.
192
+ * @property {string} apiKey - API key issued by Ledger, used to authenticate requests from your dApp.
193
+ * @property {'fatal' | 'error' | 'warn' | 'info' | 'debug'} [loggerLevel] - Verbosity of the Ledger logger.
194
+ * @property {boolean} [hideButton] - When `true`, hides the built-in Ledger floating button.
195
+ */
196
+ export type LedgerWalletConfig = {
197
+ dAppIdentifier: string;
198
+ apiKey: string;
199
+ loggerLevel?: 'fatal' | 'error' | 'warn' | 'info' | 'debug';
200
+ hideButton?: boolean;
201
+ };
202
+
189
203
  /**
190
204
  * The type WidgetConfig defines the configuration options for a widget, including API key, affiliate
191
205
  * reference, amount, blockchain and token configurations, liquidity sources, wallet types, language,
@@ -254,13 +268,18 @@ export type WidgetConfig = {
254
268
  title?: string;
255
269
  walletConnectProjectId?: string;
256
270
  trezorManifest?: TrezorManifest;
271
+ ledgerWallet?: LedgerWalletConfig;
257
272
  tonConnect?: TonConnectConfig;
258
273
  affiliate?: WidgetAffiliate;
259
274
  amount?: number;
260
275
  from?: BlockchainAndTokenConfig;
261
276
  to?: BlockchainAndTokenConfig;
262
277
  liquiditySources?: string[];
263
- wallets?: (WalletType | LegacyProviderInterface | Provider)[];
278
+ /**
279
+ * Passing a `ProviderInterface` is deprecated. Pass a hub `Provider` instead.
280
+ * Legacy providers will be removed in future versions.
281
+ */
282
+ wallets?: (WalletType | ProviderInterface | Provider)[];
264
283
  multiWallets?: boolean;
265
284
  customDestination?: boolean;
266
285
  defaultCustomDestinations?: { [blockchain: string]: string };
@@ -289,3 +308,11 @@ export type WidgetConfig = {
289
308
  };
290
309
  routing?: Routing;
291
310
  };
311
+
312
+ // TODO: remove this when ProviderInterface gets removed
313
+ export type WidgetConfigWithoutLegacyProviders = WidgetConfig & {
314
+ wallets?: Exclude<
315
+ NonNullable<WidgetConfig['wallets']>[number],
316
+ ProviderInterface
317
+ >[];
318
+ };
@@ -1,5 +1,5 @@
1
+ import type { WalletType } from '@hub3js/core';
1
2
  import type { WalletInfo } from '@rango-dev/ui';
2
- import type { WalletType } from '@rango-dev/wallets-shared';
3
3
 
4
4
  export interface Wallet {
5
5
  chain: string;
@@ -294,3 +294,9 @@ export function filterBlockchainsWithAtLeastOneToken(
294
294
  blockchainsWithAtLeastOneToken.has(blockchain.name)
295
295
  );
296
296
  }
297
+
298
+ export function detectMobileScreens(): boolean {
299
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
300
+ navigator.userAgent
301
+ );
302
+ }
@@ -0,0 +1,78 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
3
+ import {
4
+ isModuleLoadError,
5
+ tryRefineError,
6
+ tryRefineErrorMessage,
7
+ } from './errors';
8
+
9
+ describe('error refinement', () => {
10
+ describe('recognizing a failed dynamic import', () => {
11
+ test('should match a thrown error', () => {
12
+ const error = new TypeError(
13
+ 'Failed to fetch dynamically imported module: https://cdn.example/signer.js'
14
+ );
15
+
16
+ expect(isModuleLoadError(error)).toBe(true);
17
+ });
18
+
19
+ test('should match webpack failures named instead of worded', () => {
20
+ const error = new Error('Loading failed');
21
+ error.name = 'ChunkLoadError';
22
+
23
+ expect(isModuleLoadError(error)).toBe(true);
24
+ });
25
+
26
+ test('should match a message that was already stringified', () => {
27
+ expect(
28
+ isModuleLoadError('TypeError: importing a module script failed')
29
+ ).toBe(true);
30
+ });
31
+ });
32
+
33
+ describe('leaving unrecognized failures alone', () => {
34
+ test('should not match an unrelated error', () => {
35
+ expect(
36
+ isModuleLoadError(new Error('User rejected the transaction'))
37
+ ).toBe(false);
38
+ });
39
+
40
+ test('should not match empty input', () => {
41
+ expect(isModuleLoadError(null)).toBe(false);
42
+ expect(isModuleLoadError(undefined)).toBe(false);
43
+ expect(isModuleLoadError('')).toBe(false);
44
+ });
45
+ });
46
+
47
+ describe('refining into a user facing error', () => {
48
+ test('should keep the original as the cause', () => {
49
+ const error = new TypeError('failed to load module script');
50
+ const refined = tryRefineError(error);
51
+
52
+ expect(refined).toBeInstanceOf(Error);
53
+ expect(refined?.cause).toBe(error);
54
+ expect(refined?.message).not.toBe(error.message);
55
+ });
56
+
57
+ test('should return null for an unrecognized failure', () => {
58
+ expect(tryRefineError(new Error('boom'))).toBeNull();
59
+ });
60
+
61
+ test('should fall back to the given message', () => {
62
+ const fallback = 'An unknown error happened during connecting wallet.';
63
+
64
+ expect(tryRefineErrorMessage(new Error('boom'), fallback)).toBe(fallback);
65
+ });
66
+
67
+ test('should refine instead of falling back when recognized', () => {
68
+ const fallback = 'An unknown error happened during connecting wallet.';
69
+
70
+ expect(
71
+ tryRefineErrorMessage(
72
+ new TypeError('loading chunk 42 failed'),
73
+ fallback
74
+ )
75
+ ).not.toBe(fallback);
76
+ });
77
+ });
78
+ });