@rango-dev/widget-embedded 0.60.2-next.9 → 0.61.1-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 (58) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  3. package/dist/components/CustomDestination/CustomDestination.d.ts.map +1 -1
  4. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
  5. package/dist/components/Slippage/Slippage.d.ts.map +1 -1
  6. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  7. package/dist/containers/Settings/Lists.d.ts.map +1 -1
  8. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  9. package/dist/containers/Wallets/useUpdates.d.ts.map +1 -1
  10. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  11. package/dist/hooks/useSyncNotifications/useSyncNotifications.d.ts.map +1 -1
  12. package/dist/hooks/useWalletList.d.ts.map +1 -1
  13. package/dist/index.js +2 -2
  14. package/dist/index.js.map +4 -4
  15. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  16. package/dist/pages/Home.d.ts.map +1 -1
  17. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  18. package/dist/pages/SelectBlockchainPage.d.ts.map +1 -1
  19. package/dist/pages/SelectSwapItemPage/SelectSwapItemPage.helpers.d.ts +1 -0
  20. package/dist/pages/SelectSwapItemPage/SelectSwapItemPage.helpers.d.ts.map +1 -1
  21. package/dist/pages/SelectSwapItemPage/SelectSwapItemsPage.d.ts.map +1 -1
  22. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  23. package/dist/store/slices/config.d.ts.map +1 -1
  24. package/dist/store/slices/wallets.d.ts +3 -1
  25. package/dist/store/slices/wallets.d.ts.map +1 -1
  26. package/dist/types/event.d.ts +160 -6
  27. package/dist/types/event.d.ts.map +1 -1
  28. package/dist/utils/eventPayloads.d.ts +8 -0
  29. package/dist/utils/eventPayloads.d.ts.map +1 -0
  30. package/dist/utils/events.d.ts +8 -5
  31. package/dist/utils/events.d.ts.map +1 -1
  32. package/dist/utils/wallets.d.ts.map +1 -1
  33. package/dist/widget-embedded.build.json +1 -1
  34. package/package.json +9 -9
  35. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +43 -1
  36. package/src/components/CustomDestination/CustomDestination.tsx +18 -0
  37. package/src/components/Quote/QuoteCostDetails.tsx +8 -0
  38. package/src/components/Slippage/Slippage.tsx +21 -0
  39. package/src/components/SwapDetails/SwapDetails.tsx +6 -0
  40. package/src/containers/Settings/Lists.tsx +13 -1
  41. package/src/containers/Wallets/Wallets.tsx +3 -0
  42. package/src/containers/Wallets/useUpdates.ts +3 -1
  43. package/src/hooks/useSwapInput.ts +37 -1
  44. package/src/hooks/useSyncNotifications/useSyncNotifications.ts +33 -1
  45. package/src/hooks/useWalletList.ts +36 -0
  46. package/src/pages/ConfirmSwapPage.tsx +12 -1
  47. package/src/pages/Home.tsx +39 -14
  48. package/src/pages/LiquiditySourcePage.tsx +28 -0
  49. package/src/pages/SelectBlockchainPage.tsx +10 -0
  50. package/src/pages/SelectSwapItemPage/SelectSwapItemPage.helpers.ts +9 -0
  51. package/src/pages/SelectSwapItemPage/SelectSwapItemsPage.tsx +30 -0
  52. package/src/pages/SwapDetailsPage.tsx +6 -0
  53. package/src/store/slices/config.ts +0 -3
  54. package/src/store/slices/wallets.ts +10 -4
  55. package/src/types/event.ts +189 -10
  56. package/src/utils/eventPayloads.ts +39 -0
  57. package/src/utils/events.ts +33 -10
  58. package/src/utils/wallets.ts +20 -2
@@ -14,8 +14,11 @@ import { useNavigateBack } from '../../hooks/useNavigateBack';
14
14
  import { useSearchCustomTokens } from '../../hooks/useSearchCustomTokens';
15
15
  import { useAppStore } from '../../store/AppStore';
16
16
  import { useQuoteStore } from '../../store/quote';
17
+ import { UiEventTypes } from '../../types';
18
+ import { emitUiEvent } from '../../utils/events';
17
19
 
18
20
  import {
21
+ getTokenSelectionMethod,
19
22
  prepareTokensList,
20
23
  shouldSearchForCustomTokens,
21
24
  } from './SelectSwapItemPage.helpers';
@@ -82,6 +85,31 @@ export function SelectSwapItemsPage(props: PropTypes) {
82
85
  setToToken({ token, meta: { blockchains } });
83
86
  }
84
87
  };
88
+
89
+ const side = type === 'source' ? 'from' : 'to';
90
+
91
+ const emitChainFilterApplied = (blockchain: BlockchainMeta) => {
92
+ emitUiEvent({
93
+ type: UiEventTypes.CHAIN_FILTER_APPLIED,
94
+ payload: { side, chain: blockchain.name, filterSource: 'featured' },
95
+ });
96
+ };
97
+
98
+ const emitTokenSelected = (token: Token) => {
99
+ emitUiEvent({
100
+ type: UiEventTypes.TOKEN_SELECTED,
101
+ payload: {
102
+ side,
103
+ tokenName: token.name,
104
+ tokenSymbol: token.symbol,
105
+ tokenAddress: token.address,
106
+ chain: token.blockchain,
107
+ selectionMethod: getTokenSelectionMethod(searchedFor),
108
+ activeChainFilter: selectedBlockchainName || 'all',
109
+ },
110
+ });
111
+ };
112
+
85
113
  const types = {
86
114
  source: i18n.t('Source'),
87
115
  destination: i18n.t('Destination'),
@@ -111,6 +139,7 @@ export function SelectSwapItemsPage(props: PropTypes) {
111
139
  blockchain={type === 'source' ? fromBlockchain : toBlockchain}
112
140
  onMoreClick={() => navigate(navigationRoutes.blockchains)}
113
141
  onChange={(blockchain) => {
142
+ emitChainFilterApplied(blockchain);
114
143
  updateBlockchain(blockchain);
115
144
  }}
116
145
  />
@@ -142,6 +171,7 @@ export function SelectSwapItemsPage(props: PropTypes) {
142
171
  searchedFor={searchedFor}
143
172
  type={type}
144
173
  onChange={(token) => {
174
+ emitTokenSelected(token);
145
175
  updateToken(token);
146
176
 
147
177
  const tokenBlockchain = blockchains.find(
@@ -9,6 +9,8 @@ import { SwapDetails } from '../components/SwapDetails';
9
9
  import { SwapDetailsPlaceholder } from '../components/SwapDetails/SwapDetails.Placeholder';
10
10
  import { useNavigateBack } from '../hooks/useNavigateBack';
11
11
  import { useAppStore } from '../store/AppStore';
12
+ import { UiEventTypes } from '../types';
13
+ import { emitUiEvent } from '../utils/events';
12
14
  import { getPendingSwaps } from '../utils/queue';
13
15
 
14
16
  export function SwapDetailsPage() {
@@ -41,6 +43,10 @@ export function SwapDetailsPage() {
41
43
  if (selectedSwap?.id) {
42
44
  const swap = manager?.get(selectedSwap.id);
43
45
  if (swap) {
46
+ emitUiEvent({
47
+ type: UiEventTypes.SWAP_CANCELLED,
48
+ payload: { routeId: requestId },
49
+ });
44
50
  cancelSwap(swap);
45
51
  }
46
52
  }
@@ -93,9 +93,6 @@ function generateProviders(config: WidgetConfig) {
93
93
  options?.walletConnectListedDesktopWalletLink,
94
94
  },
95
95
  selectedProviders: config.wallets,
96
- trezor: options?.trezorManifest
97
- ? { manifest: options.trezorManifest }
98
- : undefined,
99
96
  tonConnect: options?.tonConnect?.manifestUrl
100
97
  ? { manifestUrl: options?.tonConnect.manifestUrl }
101
98
  : undefined,
@@ -114,7 +114,8 @@ export interface WalletsSlice {
114
114
  newWalletConnected: (
115
115
  accounts: Wallet[],
116
116
  namespace?: Namespace,
117
- derivationPath?: string
117
+ derivationPath?: string,
118
+ meta?: { walletName?: string }
118
119
  ) => Promise<void>;
119
120
  disconnectNamespaces: (walletType: string, namespaces: Namespace[]) => void;
120
121
  /**
@@ -443,14 +444,19 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
443
444
  connectedWallets: nextConnectedWalletsWithUpdatedSelectedStatus,
444
445
  });
445
446
  },
446
- newWalletConnected: async (accounts, namespace, derivationPath) => {
447
+ newWalletConnected: async (accounts, namespace, derivationPath, meta) => {
447
448
  const newAccount = accounts[0];
448
449
  if (!newAccount) {
449
450
  return;
450
451
  }
451
452
  eventEmitter.emit(WidgetEvents.WalletEvent, {
452
453
  type: WalletEventTypes.CONNECT,
453
- payload: { walletType: newAccount.walletType, accounts },
454
+ payload: {
455
+ walletType: newAccount.walletType,
456
+ accounts,
457
+ chain: newAccount.chain ?? null,
458
+ walletName: meta?.walletName ?? newAccount.walletType,
459
+ },
454
460
  });
455
461
 
456
462
  get().addConnectedWallet(accounts, namespace, derivationPath);
@@ -526,7 +532,7 @@ export const createWalletsSlice = keepLastUpdated<AppStoreState, WalletsSlice>(
526
532
  */
527
533
  eventEmitter.emit(WidgetEvents.WalletEvent, {
528
534
  type: WalletEventTypes.DISCONNECT,
529
- payload: { walletType },
535
+ payload: { walletType, walletName: walletType },
530
536
  });
531
537
  if (isTargetWalletExistsInConnectedWallets) {
532
538
  // This should be called before updating connectedWallets since we need the old state to remove balances.
@@ -5,8 +5,6 @@ import type {
5
5
  StepEventData,
6
6
  } from '@rango-dev/queue-manager-rango-preset';
7
7
 
8
- import { WidgetEvents as QueueManagerEvents } from '@rango-dev/queue-manager-rango-preset';
9
-
10
8
  type EventData<
11
9
  T extends QuoteEventTypes | WalletEventTypes | UiEventTypes,
12
10
  U extends Record<string, unknown> | null
@@ -23,11 +21,20 @@ type Account = Wallet;
23
21
  export enum QuoteEventTypes {
24
22
  QUOTE_INPUT_UPDATE = 'quoteInputUpdate',
25
23
  QUOTE_OUTPUT_UPDATE = 'quoteOutputUpdate',
24
+ /** A route/quote request was made with a valid source, destination and amount. */
25
+ ROUTE_REQUESTED = 'routeRequested',
26
+ /** The route API returned zero results for the requested pair. */
27
+ ROUTE_NOT_FOUND = 'routeNotFound',
28
+ /** The route API returned a 4xx/5xx error. */
29
+ ROUTE_FETCH_FAILED = 'routeFetchFailed',
30
+ /** The user overrode the auto-selected route. */
31
+ ROUTE_CHANGED = 'routeChanged',
26
32
  }
27
33
 
28
34
  export enum WalletEventTypes {
29
35
  CONNECT = 'connect',
30
36
  DISCONNECT = 'disconnect',
37
+ DETECTED = 'detected',
31
38
  }
32
39
 
33
40
  /**
@@ -36,6 +43,20 @@ export enum WalletEventTypes {
36
43
  */
37
44
  export enum UiEventTypes {
38
45
  CLICK_CONNECT_WALLET = 'clickConnectWallet',
46
+ TOKEN_SELECTED = 'tokenSelected',
47
+ CHAIN_FILTER_APPLIED = 'chainFilterApplied',
48
+ SETTINGS_CHANGED = 'settingsChanged',
49
+ ROUTE_FEE_VIEWED = 'routeFeeViewed',
50
+ DESTINATION_ADDRESS_SET = 'destinationAddressSet',
51
+ GAS_WARNING_SHOWN = 'gasWarningShown',
52
+ GAS_WARNING_BYPASSED = 'gasWarningBypassed',
53
+ SWAP_INITIATED = 'swapInitiated',
54
+ SWAP_WALLETS_MODAL_SHOWN = 'swapWalletsModalShown',
55
+ SWAP_WALLETS_CONFIRMED = 'swapWalletsConfirmed',
56
+ SWAP_STARTED = 'swapStarted',
57
+ SWAP_RESUMED = 'swapResumed',
58
+ SWAP_RETRIED = 'swapRetried',
59
+ SWAP_CANCELLED = 'swapCancelled',
39
60
  }
40
61
 
41
62
  export type QuoteInputUpdateEventPayload = {
@@ -54,30 +75,188 @@ export type QuoteUpdateEventPayload = Pick<
54
75
  export type ConnectWalletEventPayload = {
55
76
  walletType: string;
56
77
  accounts: Account[];
78
+ /** Blockchain of the first connected account. */
79
+ chain: string | null;
80
+ /** wallet type (e.g. "metamask"). */
81
+ walletName: string;
57
82
  };
58
83
 
59
84
  export type DisconnectWalletEventPayload = {
60
85
  walletType: string;
86
+ walletName: string;
87
+ };
88
+
89
+ export type WalletDetectedEventPayload = {
90
+ walletName: string;
61
91
  };
62
92
 
63
93
  export type ClickConnectWalletPayload = PreventableEventPayload;
64
94
 
95
+ /** Shared shape describing a route/quote, used by several swap events. */
96
+ export type SwapEstimateEventPayload = {
97
+ sourceChain: string;
98
+ destinationChain: string;
99
+ sourceTokenSymbol: string;
100
+ sourceTokenAddress: string | null;
101
+ destinationTokenSymbol: string;
102
+ destinationTokenAddress: string | null;
103
+ inputAmountUsd: number | null;
104
+ outputAmountUsd: number | null;
105
+ sourceTokenAmount: number | null;
106
+ destinationTokenAmount: number | null;
107
+ routeId: string;
108
+ };
109
+
110
+ export type RouteRequestedEventPayload = SwapEstimateEventPayload & {
111
+ routeCount: number;
112
+ };
113
+
114
+ export type RouteNotFoundEventPayload = {
115
+ sourceChain: string;
116
+ destinationChain: string;
117
+ sourceTokenSymbol: string;
118
+ sourceTokenAddress: string | null;
119
+ destinationTokenSymbol: string;
120
+ destinationTokenAddress: string | null;
121
+ inputAmountUsd: number | null;
122
+ };
123
+
124
+ export type RouteFetchFailedEventPayload = {
125
+ sourceChain: string;
126
+ destinationChain: string;
127
+ /** HTTP status code returned by the route API, as a string. */
128
+ errorCode: string;
129
+ };
130
+
131
+ export type RouteChangedEventPayload = {
132
+ sourceChain: string;
133
+ destinationChain: string;
134
+ fromRouteId: string;
135
+ toRouteId: string;
136
+ };
137
+
138
+ export type TokenSelectedEventPayload = {
139
+ side: 'from' | 'to';
140
+ tokenName: string | null;
141
+ tokenSymbol: string;
142
+ tokenAddress: string | null;
143
+ chain: string;
144
+ selectionMethod: 'search' | 'default ';
145
+ /** `all` when no chain filter is active, otherwise the filtered chain name. */
146
+ activeChainFilter: string;
147
+ };
148
+
149
+ export type ChainFilterAppliedEventPayload = {
150
+ side: 'from' | 'to';
151
+ chain: string;
152
+ filterSource: 'featured' | 'expanded';
153
+ };
154
+
155
+ export type LiquiditySourceType = 'exchanges' | 'bridges';
156
+
157
+ export type SettingsChangedEventPayload =
158
+ | { setting: 'slippage'; previousValue: number; newValue: number }
159
+ | { setting: 'infiniteApproval'; previousValue: boolean; newValue: boolean }
160
+ | {
161
+ setting: 'liquiditySource';
162
+ sourceType: LiquiditySourceType;
163
+ /** A single source was toggled on/off from the list. */
164
+ changeType: 'individual';
165
+ /** The sources whose enabled state changed, with their new state. */
166
+ sources: { id: string; enabled: boolean }[];
167
+ }
168
+ | {
169
+ setting: 'liquiditySource';
170
+ sourceType: LiquiditySourceType;
171
+ /** Every source was enabled or disabled at once via the header button. */
172
+ changeType: 'selectAll' | 'deselectAll';
173
+ /**
174
+ * Selection state before the bulk action, so the consumer can summarise
175
+ * it as all/some/none.
176
+ */
177
+ previousSelectedCount: number;
178
+ totalCount: number;
179
+ };
180
+
181
+ export type RouteFeeViewedEventPayload = { routeId: string };
182
+
183
+ export type DestinationAddressSetEventPayload = { destinationChain: string };
184
+
185
+ export type GasWarningEventPayload = { routeId: string };
186
+
187
+ export type SwapInitiatedEventPayload = SwapEstimateEventPayload & {
188
+ walletConnected: boolean;
189
+ };
190
+
191
+ export type SwapStartedEventPayload = SwapEstimateEventPayload & {
192
+ stepCount: number;
193
+ };
194
+
195
+ export type SwapWalletsModalShownEventPayload = {
196
+ chainsRequired: number;
197
+ chainsPending: number;
198
+ };
199
+
200
+ export type SwapWalletsConfirmedEventPayload = { routeId: string };
201
+
202
+ export type SwapResumedEventPayload = {
203
+ routeId: string;
204
+ stepCount: number;
205
+ stepNumber: number;
206
+ };
207
+
208
+ export type SwapRetriedEventPayload = { routeId: string };
209
+
210
+ export type SwapCancelledEventPayload = { routeId: string };
211
+
65
212
  export type QuoteEventData =
66
213
  | EventData<QuoteEventTypes.QUOTE_INPUT_UPDATE, QuoteInputUpdateEventPayload>
67
- | EventData<QuoteEventTypes.QUOTE_OUTPUT_UPDATE, QuoteUpdateEventPayload>;
214
+ | EventData<QuoteEventTypes.QUOTE_OUTPUT_UPDATE, QuoteUpdateEventPayload>
215
+ | EventData<QuoteEventTypes.ROUTE_REQUESTED, RouteRequestedEventPayload>
216
+ | EventData<QuoteEventTypes.ROUTE_NOT_FOUND, RouteNotFoundEventPayload>
217
+ | EventData<QuoteEventTypes.ROUTE_FETCH_FAILED, RouteFetchFailedEventPayload>
218
+ | EventData<QuoteEventTypes.ROUTE_CHANGED, RouteChangedEventPayload>;
68
219
 
69
220
  export type WalletEventData =
70
221
  | EventData<WalletEventTypes.CONNECT, ConnectWalletEventPayload>
71
- | EventData<WalletEventTypes.DISCONNECT, DisconnectWalletEventPayload>;
222
+ | EventData<WalletEventTypes.DISCONNECT, DisconnectWalletEventPayload>
223
+ | EventData<WalletEventTypes.DETECTED, WalletDetectedEventPayload>;
72
224
 
73
- export type UiEventData = EventData<
74
- UiEventTypes.CLICK_CONNECT_WALLET,
75
- ClickConnectWalletPayload
76
- >;
225
+ export type UiEventData =
226
+ | EventData<UiEventTypes.CLICK_CONNECT_WALLET, ClickConnectWalletPayload>
227
+ | EventData<UiEventTypes.TOKEN_SELECTED, TokenSelectedEventPayload>
228
+ | EventData<UiEventTypes.CHAIN_FILTER_APPLIED, ChainFilterAppliedEventPayload>
229
+ | EventData<UiEventTypes.SETTINGS_CHANGED, SettingsChangedEventPayload>
230
+ | EventData<UiEventTypes.ROUTE_FEE_VIEWED, RouteFeeViewedEventPayload>
231
+ | EventData<
232
+ UiEventTypes.DESTINATION_ADDRESS_SET,
233
+ DestinationAddressSetEventPayload
234
+ >
235
+ | EventData<UiEventTypes.GAS_WARNING_SHOWN, GasWarningEventPayload>
236
+ | EventData<UiEventTypes.GAS_WARNING_BYPASSED, GasWarningEventPayload>
237
+ | EventData<UiEventTypes.SWAP_INITIATED, SwapInitiatedEventPayload>
238
+ | EventData<
239
+ UiEventTypes.SWAP_WALLETS_MODAL_SHOWN,
240
+ SwapWalletsModalShownEventPayload
241
+ >
242
+ | EventData<
243
+ UiEventTypes.SWAP_WALLETS_CONFIRMED,
244
+ SwapWalletsConfirmedEventPayload
245
+ >
246
+ | EventData<UiEventTypes.SWAP_STARTED, SwapStartedEventPayload>
247
+ | EventData<UiEventTypes.SWAP_RESUMED, SwapResumedEventPayload>
248
+ | EventData<UiEventTypes.SWAP_RETRIED, SwapRetriedEventPayload>
249
+ | EventData<UiEventTypes.SWAP_CANCELLED, SwapCancelledEventPayload>;
77
250
 
251
+ /**
252
+ * RouteEvent/StepEvent must match the queue-manager's `WidgetEvents` string
253
+ * values (`QueueManagerEvents`) so events route correctly. They're inlined as
254
+ * literals rather than referencing the other enum to keep this a pure string
255
+ * enum (a cross-enum reference makes `no-mixed-enums` read them as numeric).
256
+ */
78
257
  export enum WidgetEvents {
79
- RouteEvent = QueueManagerEvents.RouteEvent,
80
- StepEvent = QueueManagerEvents.StepEvent,
258
+ RouteEvent = 'routeEvent',
259
+ StepEvent = 'stepEvent',
81
260
  QuoteEvent = 'quoteEvent',
82
261
  WalletEvent = 'walletEvent',
83
262
  UiEvent = 'uiEvent',
@@ -0,0 +1,39 @@
1
+ import type { SelectedQuote, SwapEstimateEventPayload } from '../types';
2
+
3
+ import { getUsdInputFrom, getUsdOutputFrom } from './swap';
4
+
5
+ function toNumberOrNull(value: string | null | undefined): number | null {
6
+ if (value === null || value === undefined || value === '') {
7
+ return null;
8
+ }
9
+ const parsed = Number(value);
10
+ return Number.isFinite(parsed) ? parsed : null;
11
+ }
12
+
13
+ /**
14
+ * Derives the shared route/quote descriptor used by several swap
15
+ * events (swapInitiated, swapStarted, routeRequested, ...) from a quote.
16
+ * Amounts are estimates taken from the quote, not on-chain actuals.
17
+ */
18
+ export function buildSwapEstimatePayload(
19
+ quote: SelectedQuote
20
+ ): SwapEstimateEventPayload {
21
+ const firstSwap = quote.swaps[0];
22
+ const lastSwap = quote.swaps[quote.swaps.length - 1];
23
+ const inputUsd = getUsdInputFrom(quote);
24
+ const outputUsd = getUsdOutputFrom(quote);
25
+
26
+ return {
27
+ routeId: quote.requestId,
28
+ sourceChain: firstSwap?.from.blockchain ?? '',
29
+ destinationChain: lastSwap?.to.blockchain ?? '',
30
+ sourceTokenSymbol: firstSwap?.from.symbol ?? '',
31
+ sourceTokenAddress: firstSwap?.from.address ?? null,
32
+ destinationTokenSymbol: lastSwap?.to.symbol ?? '',
33
+ destinationTokenAddress: lastSwap?.to.address ?? null,
34
+ sourceTokenAmount: toNumberOrNull(quote.requestAmount),
35
+ destinationTokenAmount: toNumberOrNull(quote.outputAmount),
36
+ inputAmountUsd: inputUsd ? inputUsd.toNumber() : null,
37
+ outputAmountUsd: outputUsd ? outputUsd.toNumber() : null,
38
+ };
39
+ }
@@ -1,27 +1,50 @@
1
1
  import { eventEmitter } from '../services/eventEmitter';
2
- import { type UiEventData, WidgetEvents } from '../types';
2
+ import {
3
+ type ClickConnectWalletPayload,
4
+ type QuoteEventData,
5
+ type UiEventData,
6
+ type UiEventTypes,
7
+ type WalletDetectedEventPayload,
8
+ WalletEventTypes,
9
+ WidgetEvents,
10
+ } from '../types';
3
11
 
4
- type UiEvent = {
5
- type: UiEventData['type'];
6
- payload?: Omit<UiEventData['payload'], 'preventDefault'>;
12
+ type PreventableUiEvent = {
13
+ type: UiEventTypes.CLICK_CONNECT_WALLET;
14
+ payload?: Omit<ClickConnectWalletPayload, 'preventDefault'>;
7
15
  };
8
16
 
9
- export function emitPreventableEvent(event: UiEvent, action: () => void): void {
17
+ export function emitUiEvent(event: UiEventData): void {
18
+ eventEmitter.emit(WidgetEvents.UiEvent, event);
19
+ }
20
+
21
+ export function emitPreventableEvent(
22
+ event: PreventableUiEvent,
23
+ action: () => void
24
+ ): void {
10
25
  let defaultPrevented = false;
11
26
 
12
27
  const extendedPayload = {
28
+ ...event.payload,
13
29
  preventDefault() {
14
30
  defaultPrevented = true;
15
31
  },
16
- ...(event.payload === undefined && { payload: event.payload }),
17
32
  };
18
33
 
19
- eventEmitter.emit(WidgetEvents.UiEvent, {
20
- type: event.type,
21
- payload: extendedPayload,
22
- });
34
+ emitUiEvent({ type: event.type, payload: extendedPayload });
23
35
 
24
36
  if (!defaultPrevented) {
25
37
  action();
26
38
  }
27
39
  }
40
+
41
+ export function emitQuoteEvent(event: QuoteEventData): void {
42
+ eventEmitter.emit(WidgetEvents.QuoteEvent, event);
43
+ }
44
+
45
+ export function emitWalletDetected(payload: WalletDetectedEventPayload): void {
46
+ eventEmitter.emit(WidgetEvents.WalletEvent, {
47
+ type: WalletEventTypes.DETECTED,
48
+ payload,
49
+ });
50
+ }
@@ -24,6 +24,7 @@ import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/walle
24
24
  import {
25
25
  detectInstallLink,
26
26
  HYPERLIQUID_SIGN_NETWORK,
27
+ getBlockChainNameFromId,
27
28
  isEvmAddress,
28
29
  Networks,
29
30
  } from '@rango-dev/wallets-shared';
@@ -45,6 +46,20 @@ import { formatThousandsWithCommas } from './sanitizers';
45
46
  export type ExtendedModalWalletInfo = WalletInfoWithExtra &
46
47
  Pick<ExtendedWalletInfo, 'properties' | 'isHub'>;
47
48
 
49
+ function getConnectedEvmChainName(
50
+ namespaces: ReturnType<ProviderContext['state']>['namespaces'],
51
+ supportedChains: BlockchainMeta[]
52
+ ): string | null {
53
+ const evmNamespace = namespaces?.get('EVM');
54
+ if (!!evmNamespace?.network) {
55
+ return (
56
+ getBlockChainNameFromId(evmNamespace.network, supportedChains) ??
57
+ evmNamespace.network
58
+ );
59
+ }
60
+ return null;
61
+ }
62
+
48
63
  export function getWalletConnectionStatus(
49
64
  wallet: ExtendedWalletInfo,
50
65
  walletState: ReturnType<ProviderContext['state']>
@@ -75,9 +90,12 @@ export function mapWalletTypesToWalletInfo(
75
90
  .filter((wallet) => {
76
91
  const { supportedChains, isContractWallet } = getWalletInfo(wallet);
77
92
 
78
- const { installed, network } = getState(wallet);
93
+ const { installed, namespaces } = getState(wallet);
79
94
  const filterContractWallets =
80
- isContractWallet && (!installed || (!!chain && network !== chain));
95
+ isContractWallet &&
96
+ (!installed ||
97
+ (!!chain &&
98
+ getConnectedEvmChainName(namespaces, supportedChains) !== chain));
81
99
  if (filterContractWallets) {
82
100
  return false;
83
101
  }