@rango-dev/wallets-react 0.0.0-experimental-c6bea4d8-20260930 → 0.0.0-experimental-2938686c-20261012

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.
@@ -1,13 +1,16 @@
1
1
  import type { AllProxiedNamespaces, ExtensionLink } from './types.js';
2
2
  import type {
3
3
  ConnectResult,
4
+ EventHandler,
4
5
  NamespaceInputForConnect,
5
6
  WalletInfo,
6
7
  } from '../legacy/mod.js';
7
8
  import type { ProviderContext, ProviderProps } from '../types.js';
8
9
  import type { Provider, WalletType } from '@hub3js/core';
10
+ import type { Event } from '@hub3js/core/store';
9
11
  import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
10
12
 
13
+ import { Hub3Error } from '@hub3js/core';
11
14
  import {
12
15
  getSupportedChainsFromNamespace,
13
16
  getSupportedChainsFromProvider,
@@ -15,16 +18,18 @@ import {
15
18
  import { useEffect, useRef, useState } from 'react';
16
19
  import { Ok, Result } from 'ts-results';
17
20
 
18
- import { withErrorLoggingApi } from '../helpers.js';
21
+ import {
22
+ emitWalletDetectedOnce,
23
+ toBlockchainName,
24
+ WalletEventChannel,
25
+ WalletEventTypes,
26
+ } from '../events.js';
27
+ import { Events } from '../legacy/mod.js';
19
28
 
20
29
  import { autoConnect } from './autoConnect.js';
21
30
  import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
22
31
  import { reportConnectionFailure } from './errors.js';
23
- import {
24
- createQueue,
25
- fromAccountIdToLegacyAddressFormat,
26
- removeQueuedNamespacesOnRejection,
27
- } from './helpers.js';
32
+ import { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';
28
33
  import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
29
34
  import { useAutoConnect } from './useAutoConnect.js';
30
35
  import { useHubRefs } from './useHubRefs.js';
@@ -49,6 +54,7 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
49
54
  const dataRef = useRef({
50
55
  onUpdateState: params.onUpdateState,
51
56
  allBlockChains: params.allBlockChains,
57
+ emitter: params.emitter,
52
58
  });
53
59
  const hubInitiated = useRef(false);
54
60
 
@@ -68,37 +74,43 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
68
74
  };
69
75
 
70
76
  const queueTask = createQueue({
71
- onError: removeQueuedNamespacesOnRejection,
77
+ // Once the user rejects one of a wallet's namespaces, or the wallet is locked, its remaining queued namespaces are abandoned.
78
+ onError: (error, actions) => {
79
+ if (error instanceof Hub3Error && error.type !== 'PROVIDER_UNEXPECTED') {
80
+ actions.removeCurrentKeyFromQueue();
81
+ }
82
+ },
72
83
  });
73
84
 
74
85
  useEffect(() => {
75
86
  dataRef.current = {
76
87
  onUpdateState: params.onUpdateState,
77
88
  allBlockChains: params.allBlockChains,
89
+ emitter: params.emitter,
78
90
  };
79
91
  }, [params]);
80
92
 
81
93
  useEffect(() => {
82
- getStore()
83
- .subscribe((event) => {
84
- if (dataRef.current.onUpdateState) {
85
- try {
86
- mapHubEventsToLegacy(
87
- getHub(),
88
- event,
89
- dataRef.current.onUpdateState,
90
- {
91
- allBlockChains: dataRef.current.allBlockChains,
92
- lastConnectAttemptParams: lastConnectAttemptParamsRef.current,
93
- }
94
- );
95
- } catch (e) {
96
- console.error(e);
97
- }
98
- }
99
- rerender((currentRender) => currentRender + 1);
100
- })
101
- .flushEvents();
94
+ const onUpdateState: EventHandler = (type, event, value, state, info) => {
95
+ if (event === Events.INSTALLED && state.installed) {
96
+ emitWalletDetectedOnce(type, dataRef.current.emitter);
97
+ }
98
+ dataRef.current.onUpdateState?.(type, event, value, state, info);
99
+ };
100
+
101
+ const onStoreEvent = (event: Event) => {
102
+ try {
103
+ mapHubEventsToLegacy(getHub(), event, onUpdateState, {
104
+ allBlockChains: dataRef.current.allBlockChains,
105
+ lastConnectAttemptParams: lastConnectAttemptParamsRef.current,
106
+ });
107
+ } catch (e) {
108
+ console.error(e);
109
+ }
110
+ rerender((currentRender) => currentRender + 1);
111
+ };
112
+
113
+ getStore().subscribe(onStoreEvent).flushEvents();
102
114
  }, []);
103
115
 
104
116
  // Initialize hub only after blockchain meta is available (e.g. WalletConnect needs it at init).
@@ -120,6 +132,7 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
120
132
  allBlockChains: params.allBlockChains,
121
133
  getHub,
122
134
  wallets: params.configs?.wallets,
135
+ emitter: dataRef.current.emitter,
123
136
  });
124
137
  },
125
138
  });
@@ -266,7 +279,46 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
266
279
  },
267
280
  };
268
281
  });
269
- return queueTask(connectNamespaceProcess, type);
282
+
283
+ // Reconnecting an already connected namespace (e.g. only to switch its network) isn't reported.
284
+ const connectNamespaceProcessWithEvents = async () => {
285
+ if (namespace.state()[0]().connected) {
286
+ return connectNamespaceProcess();
287
+ }
288
+
289
+ const eventPayload = {
290
+ walletName: type,
291
+ namespace: namespaceInput.namespace,
292
+ origin: 'manual' as const,
293
+ };
294
+ const requestedChain = namespaceInput.network || null;
295
+
296
+ dataRef.current.emitter?.emit(WalletEventChannel, {
297
+ type: WalletEventTypes.WALLET_CONNECT_INITIATED,
298
+ payload: { ...eventPayload, chain: requestedChain },
299
+ });
300
+ try {
301
+ const result = await connectNamespaceProcess();
302
+ dataRef.current.emitter?.emit(WalletEventChannel, {
303
+ type: WalletEventTypes.WALLET_CONNECTED,
304
+ payload: {
305
+ ...eventPayload,
306
+ chain: toBlockchainName(
307
+ result.response.network,
308
+ params.allBlockChains
309
+ ),
310
+ },
311
+ });
312
+ return result;
313
+ } catch (error) {
314
+ dataRef.current.emitter?.emit(WalletEventChannel, {
315
+ type: WalletEventTypes.WALLET_CONNECT_FAILED,
316
+ payload: { ...eventPayload, chain: requestedChain },
317
+ });
318
+ throw error;
319
+ }
320
+ };
321
+ return queueTask(connectNamespaceProcessWithEvents, type);
270
322
  }
271
323
  );
272
324
 
@@ -320,6 +372,10 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
320
372
  !namespaces || namespaces.includes(namespace.namespaceId);
321
373
  const namespaceIsConnected = namespace.state()[0]().connected;
322
374
  if (namespaceShouldBeDisconnected && namespaceIsConnected) {
375
+ dataRef.current.emitter?.emit(WalletEventChannel, {
376
+ type: WalletEventTypes.WALLET_DISCONNECTED,
377
+ payload: { walletName: type, namespace: namespace.namespaceId },
378
+ });
323
379
  return namespace.disconnect();
324
380
  }
325
381
  });
@@ -518,5 +574,5 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
518
574
  },
519
575
  };
520
576
 
521
- return withErrorLoggingApi(api);
577
+ return api;
522
578
  }
package/src/index.ts CHANGED
@@ -1,4 +1,16 @@
1
1
  export { default as Provider } from './provider.js';
2
2
  export { useWallets } from './hooks.js';
3
3
  export type * from './types.js';
4
+ export { WalletEventChannel, WalletEventTypes } from './events.js';
5
+ export type {
6
+ Emitter,
7
+ WalletConnectedEventPayload,
8
+ WalletConnectFailedEventPayload,
9
+ WalletConnectInitiatedEventPayload,
10
+ WalletConnectOrigin,
11
+ WalletDetectedEventPayload,
12
+ WalletDisconnectedEventPayload,
13
+ WalletEventData,
14
+ WalletEvents,
15
+ } from './events.js';
4
16
  export * from './legacy/types.js';
package/src/types.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Emitter, WalletEvents } from './events.js';
1
2
  import type {
2
3
  ConnectResult,
3
4
  EventHandler,
@@ -43,6 +44,8 @@ export type ProviderProps = PropsWithChildren<{
43
44
  allBlockChains?: BlockchainMeta[];
44
45
  autoConnect?: boolean;
45
46
  providers: Provider[];
47
+ /** Receives wallet events on the `walletEvent` channel. */
48
+ emitter?: Emitter<WalletEvents>;
46
49
  configs?: {
47
50
  wallets?: (WalletType | Provider)[];
48
51
  walletOptions?: {