@rango-dev/wallets-react 0.49.2-next.3 → 0.49.2-next.5
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.
- package/dist/events.d.ts +49 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/hub/autoConnect.d.ts +2 -0
- package/dist/hub/autoConnect.d.ts.map +1 -1
- package/dist/hub/constants.d.ts +1 -0
- package/dist/hub/constants.d.ts.map +1 -1
- package/dist/hub/useHubAdapter.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/walletEvents.test.d.ts +2 -0
- package/dist/walletEvents.test.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/events.ts +99 -0
- package/src/hub/autoConnect.ts +55 -3
- package/src/hub/constants.ts +12 -0
- package/src/hub/useHubAdapter.ts +76 -21
- package/src/index.ts +12 -0
- package/src/types.ts +3 -0
- package/src/walletEvents.test.tsx +533 -0
package/src/hub/autoConnect.ts
CHANGED
|
@@ -7,14 +7,34 @@ import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
|
|
|
7
7
|
|
|
8
8
|
import { Result } from 'ts-results';
|
|
9
9
|
|
|
10
|
+
import {
|
|
11
|
+
toBlockchainName,
|
|
12
|
+
WalletEventChannel,
|
|
13
|
+
type WalletEventEmitter,
|
|
14
|
+
WalletEventTypes,
|
|
15
|
+
} from '../events.js';
|
|
16
|
+
|
|
10
17
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
11
18
|
import { runSequentiallyWithoutFailure } from './helpers.js';
|
|
12
19
|
import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
|
|
13
20
|
import {
|
|
14
21
|
convertNamespaceNetworkToEvmChainId,
|
|
15
22
|
isEvmNamespace,
|
|
23
|
+
transformHubResultToLegacyResult,
|
|
16
24
|
} from './utils.js';
|
|
17
25
|
|
|
26
|
+
function createAutoConnectEventPayload(
|
|
27
|
+
walletName: WalletType,
|
|
28
|
+
namespaceInput: NamespaceInputForConnect
|
|
29
|
+
) {
|
|
30
|
+
return {
|
|
31
|
+
walletName,
|
|
32
|
+
namespace: namespaceInput.namespace,
|
|
33
|
+
chain: namespaceInput.network || null,
|
|
34
|
+
origin: 'auto' as const,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
18
38
|
function isEvmNamespaceInput(
|
|
19
39
|
namespace: NamespaceInputForConnect
|
|
20
40
|
): namespace is NamespaceInputForConnect<'EVM'> {
|
|
@@ -35,9 +55,10 @@ async function eagerConnect(
|
|
|
35
55
|
params: {
|
|
36
56
|
getHub: () => Hub;
|
|
37
57
|
allBlockChains: UseAdapterParams['allBlockChains'];
|
|
58
|
+
emitter?: WalletEventEmitter;
|
|
38
59
|
}
|
|
39
60
|
) {
|
|
40
|
-
const { getHub, allBlockChains } = params;
|
|
61
|
+
const { getHub, allBlockChains, emitter } = params;
|
|
41
62
|
const wallet = getHub().get(type);
|
|
42
63
|
if (!wallet) {
|
|
43
64
|
throw new Error(
|
|
@@ -81,10 +102,25 @@ async function eagerConnect(
|
|
|
81
102
|
} else {
|
|
82
103
|
connectNamespacePromise = async () => namespace.connect();
|
|
83
104
|
}
|
|
105
|
+
const eventPayload = createAutoConnectEventPayload(type, info);
|
|
84
106
|
try {
|
|
85
|
-
await connectNamespacePromise();
|
|
107
|
+
const result = await connectNamespacePromise();
|
|
108
|
+
emitter?.emit(WalletEventChannel, {
|
|
109
|
+
type: WalletEventTypes.WALLET_CONNECTED,
|
|
110
|
+
payload: {
|
|
111
|
+
...eventPayload,
|
|
112
|
+
chain: toBlockchainName(
|
|
113
|
+
transformHubResultToLegacyResult(result).network,
|
|
114
|
+
allBlockChains
|
|
115
|
+
),
|
|
116
|
+
},
|
|
117
|
+
});
|
|
86
118
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
119
|
} catch (e: any) {
|
|
120
|
+
emitter?.emit(WalletEventChannel, {
|
|
121
|
+
type: WalletEventTypes.WALLET_CONNECT_FAILED,
|
|
122
|
+
payload: eventPayload,
|
|
123
|
+
});
|
|
88
124
|
/*
|
|
89
125
|
* Since we check for connect failures using `instanceof Error`
|
|
90
126
|
* this check is added here to make sure the thrown error always is an instance of `Error`
|
|
@@ -182,8 +218,9 @@ export async function autoConnect(deps: {
|
|
|
182
218
|
getHub: () => Hub;
|
|
183
219
|
allBlockChains: UseAdapterParams['allBlockChains'];
|
|
184
220
|
wallets?: (WalletType | Provider)[];
|
|
221
|
+
emitter?: WalletEventEmitter;
|
|
185
222
|
}): Promise<void> {
|
|
186
|
-
const { getHub, allBlockChains, wallets } = deps;
|
|
223
|
+
const { getHub, allBlockChains, wallets, emitter } = deps;
|
|
187
224
|
const lastConnectedWallets = lastConnectedWalletsFromStorage.list();
|
|
188
225
|
const walletIds = Object.keys(lastConnectedWallets);
|
|
189
226
|
|
|
@@ -219,9 +256,23 @@ export async function autoConnect(deps: {
|
|
|
219
256
|
return;
|
|
220
257
|
}
|
|
221
258
|
|
|
259
|
+
lastConnectedNamespaces.forEach((namespace) => {
|
|
260
|
+
emitter?.emit(WalletEventChannel, {
|
|
261
|
+
type: WalletEventTypes.WALLET_CONNECT_INITIATED,
|
|
262
|
+
payload: createAutoConnectEventPayload(providerName, namespace),
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
222
266
|
const { successNamespaces, failedNamespaces } =
|
|
223
267
|
await tryRunCanEagerConnect(lastConnectedNamespaces, wallet);
|
|
224
268
|
|
|
269
|
+
failedNamespaces.forEach((namespace) => {
|
|
270
|
+
emitter?.emit(WalletEventChannel, {
|
|
271
|
+
type: WalletEventTypes.WALLET_CONNECT_FAILED,
|
|
272
|
+
payload: createAutoConnectEventPayload(providerName, namespace),
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
225
276
|
if (!successNamespaces.length) {
|
|
226
277
|
walletsToRemoveFromPersistence.push(providerName);
|
|
227
278
|
return;
|
|
@@ -235,6 +286,7 @@ export async function autoConnect(deps: {
|
|
|
235
286
|
eagerConnect(providerName, successNamespaces, {
|
|
236
287
|
allBlockChains,
|
|
237
288
|
getHub,
|
|
289
|
+
emitter,
|
|
238
290
|
}).catch((error) => console.warn(error))
|
|
239
291
|
);
|
|
240
292
|
});
|
package/src/hub/constants.ts
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
+
import { WalletTypes } from '@rango-dev/provider-all';
|
|
2
|
+
|
|
1
3
|
export const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets';
|
|
4
|
+
|
|
5
|
+
// Wallets that always report themselves installed (hardware wallets and connection protocols).
|
|
6
|
+
export const WALLET_DETECTED_SKIPPED_IDS: string[] = [
|
|
7
|
+
WalletTypes.LEDGER,
|
|
8
|
+
WalletTypes.TREZOR,
|
|
9
|
+
WalletTypes.LEDGER_WALLET,
|
|
10
|
+
WalletTypes.WALLET_CONNECT_2,
|
|
11
|
+
WalletTypes.TON_CONNECT,
|
|
12
|
+
WalletTypes.DEFAULT,
|
|
13
|
+
];
|
package/src/hub/useHubAdapter.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
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
|
|
|
11
13
|
import { utils } from '@hub3js/evm';
|
|
@@ -16,7 +18,14 @@ import {
|
|
|
16
18
|
import { useEffect, useRef, useState } from 'react';
|
|
17
19
|
import { Ok, Result } from 'ts-results';
|
|
18
20
|
|
|
21
|
+
import {
|
|
22
|
+
emitWalletDetectedOnce,
|
|
23
|
+
toBlockchainName,
|
|
24
|
+
WalletEventChannel,
|
|
25
|
+
WalletEventTypes,
|
|
26
|
+
} from '../events.js';
|
|
19
27
|
import { withErrorLoggingApi } from '../helpers.js';
|
|
28
|
+
import { Events } from '../legacy/mod.js';
|
|
20
29
|
|
|
21
30
|
import { autoConnect } from './autoConnect.js';
|
|
22
31
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
@@ -45,6 +54,7 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
45
54
|
const dataRef = useRef({
|
|
46
55
|
onUpdateState: params.onUpdateState,
|
|
47
56
|
allBlockChains: params.allBlockChains,
|
|
57
|
+
emitter: params.emitter,
|
|
48
58
|
});
|
|
49
59
|
const hubInitiated = useRef(false);
|
|
50
60
|
|
|
@@ -75,30 +85,31 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
75
85
|
dataRef.current = {
|
|
76
86
|
onUpdateState: params.onUpdateState,
|
|
77
87
|
allBlockChains: params.allBlockChains,
|
|
88
|
+
emitter: params.emitter,
|
|
78
89
|
};
|
|
79
90
|
}, [params]);
|
|
80
91
|
|
|
81
92
|
useEffect(() => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
const onUpdateState: EventHandler = (type, event, value, state, info) => {
|
|
94
|
+
if (event === Events.INSTALLED && state.installed) {
|
|
95
|
+
emitWalletDetectedOnce(type, dataRef.current.emitter);
|
|
96
|
+
}
|
|
97
|
+
dataRef.current.onUpdateState?.(type, event, value, state, info);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const onStoreEvent = (event: Event) => {
|
|
101
|
+
try {
|
|
102
|
+
mapHubEventsToLegacy(getHub(), event, onUpdateState, {
|
|
103
|
+
allBlockChains: dataRef.current.allBlockChains,
|
|
104
|
+
lastConnectAttemptParams: lastConnectAttemptParamsRef.current,
|
|
105
|
+
});
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.error(e);
|
|
108
|
+
}
|
|
109
|
+
rerender((currentRender) => currentRender + 1);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
getStore().subscribe(onStoreEvent).flushEvents();
|
|
102
113
|
}, []);
|
|
103
114
|
|
|
104
115
|
// Initialize hub only after blockchain meta is available (e.g. WalletConnect needs it at init).
|
|
@@ -120,6 +131,7 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
120
131
|
allBlockChains: params.allBlockChains,
|
|
121
132
|
getHub,
|
|
122
133
|
wallets: params.configs?.wallets,
|
|
134
|
+
emitter: dataRef.current.emitter,
|
|
123
135
|
});
|
|
124
136
|
},
|
|
125
137
|
});
|
|
@@ -258,7 +270,46 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
258
270
|
},
|
|
259
271
|
};
|
|
260
272
|
});
|
|
261
|
-
|
|
273
|
+
|
|
274
|
+
// Reconnecting an already connected namespace (e.g. only to switch its network) isn't reported.
|
|
275
|
+
const connectNamespaceProcessWithEvents = async () => {
|
|
276
|
+
if (namespace.state()[0]().connected) {
|
|
277
|
+
return connectNamespaceProcess();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const eventPayload = {
|
|
281
|
+
walletName: type,
|
|
282
|
+
namespace: namespaceInput.namespace,
|
|
283
|
+
origin: 'manual' as const,
|
|
284
|
+
};
|
|
285
|
+
const requestedChain = namespaceInput.network || null;
|
|
286
|
+
|
|
287
|
+
dataRef.current.emitter?.emit(WalletEventChannel, {
|
|
288
|
+
type: WalletEventTypes.WALLET_CONNECT_INITIATED,
|
|
289
|
+
payload: { ...eventPayload, chain: requestedChain },
|
|
290
|
+
});
|
|
291
|
+
try {
|
|
292
|
+
const result = await connectNamespaceProcess();
|
|
293
|
+
dataRef.current.emitter?.emit(WalletEventChannel, {
|
|
294
|
+
type: WalletEventTypes.WALLET_CONNECTED,
|
|
295
|
+
payload: {
|
|
296
|
+
...eventPayload,
|
|
297
|
+
chain: toBlockchainName(
|
|
298
|
+
result.response.network,
|
|
299
|
+
params.allBlockChains
|
|
300
|
+
),
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
return result;
|
|
304
|
+
} catch (error) {
|
|
305
|
+
dataRef.current.emitter?.emit(WalletEventChannel, {
|
|
306
|
+
type: WalletEventTypes.WALLET_CONNECT_FAILED,
|
|
307
|
+
payload: { ...eventPayload, chain: requestedChain },
|
|
308
|
+
});
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
return queueTask(connectNamespaceProcessWithEvents, type);
|
|
262
313
|
}
|
|
263
314
|
);
|
|
264
315
|
|
|
@@ -312,6 +363,10 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
312
363
|
!namespaces || namespaces.includes(namespace.namespaceId);
|
|
313
364
|
const namespaceIsConnected = namespace.state()[0]().connected;
|
|
314
365
|
if (namespaceShouldBeDisconnected && namespaceIsConnected) {
|
|
366
|
+
dataRef.current.emitter?.emit(WalletEventChannel, {
|
|
367
|
+
type: WalletEventTypes.WALLET_DISCONNECTED,
|
|
368
|
+
payload: { walletName: type, namespace: namespace.namespaceId },
|
|
369
|
+
});
|
|
315
370
|
return namespace.disconnect();
|
|
316
371
|
}
|
|
317
372
|
});
|
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?: {
|