@rango-dev/wallets-react 0.0.0-experimental-99f1781b-20260920 → 0.0.0-experimental-a84f27a7-20260921
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/hub/autoConnect.d.ts +0 -2
- package/dist/hub/autoConnect.d.ts.map +1 -1
- package/dist/hub/helpers.d.ts +3 -25
- package/dist/hub/helpers.d.ts.map +1 -1
- package/dist/hub/useHubAdapter.d.ts.map +1 -1
- package/dist/hub/utils.d.ts +1 -3
- package/dist/hub/utils.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/legacy/types.d.ts +1 -6
- package/dist/legacy/types.d.ts.map +1 -1
- package/package.json +11 -11
- package/src/hub/autoConnect.ts +25 -38
- package/src/hub/helpers.ts +16 -80
- package/src/hub/useHubAdapter.ts +108 -106
- package/src/hub/utils.ts +15 -36
- package/src/index.ts +0 -4
- package/src/legacy/types.ts +0 -5
- package/dist/errors.d.ts +0 -60
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.test.d.ts +0 -2
- package/dist/errors.test.d.ts.map +0 -1
- package/dist/hub/autoConnect.test.d.ts +0 -2
- package/dist/hub/autoConnect.test.d.ts.map +0 -1
- package/dist/hub/helpers.test.d.ts +0 -2
- package/dist/hub/helpers.test.d.ts.map +0 -1
- package/dist/hub/useHubAdapter.test.d.ts +0 -2
- package/dist/hub/useHubAdapter.test.d.ts.map +0 -1
- package/src/errors.test.ts +0 -349
- package/src/errors.ts +0 -124
- package/src/hub/autoConnect.test.ts +0 -193
- package/src/hub/helpers.test.ts +0 -138
- package/src/hub/useHubAdapter.test.ts +0 -186
package/src/hub/autoConnect.ts
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import type { AllProxiedNamespaces } from './types.js';
|
|
2
2
|
import type { UseAdapterParams } from './useHubAdapter.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
EventHandler,
|
|
6
|
-
NamespaceInputForConnect,
|
|
7
|
-
} from '../legacy/types.js';
|
|
3
|
+
import type { NamespaceInputForConnect } from '../legacy/types.js';
|
|
8
4
|
import type { Hub, Provider, WalletType } from '@hub3js/core';
|
|
9
5
|
import type { DefaultNamespaces, Namespace } from '@hub3js/namespaces';
|
|
10
6
|
import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
|
|
11
7
|
|
|
12
8
|
import { Result } from 'ts-results';
|
|
13
9
|
|
|
14
|
-
import { buildAutoConnectionAttemptError } from '../errors.js';
|
|
15
|
-
import { Events } from '../legacy/types.js';
|
|
16
|
-
|
|
17
10
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
18
|
-
import {
|
|
11
|
+
import { runSequentiallyWithoutFailure } from './helpers.js';
|
|
19
12
|
import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
|
|
20
13
|
import {
|
|
21
14
|
convertNamespaceNetworkToEvmChainId,
|
|
22
|
-
getProviderCoreState,
|
|
23
|
-
getProviderEventInfo,
|
|
24
15
|
isEvmNamespace,
|
|
25
16
|
} from './utils.js';
|
|
26
17
|
|
|
@@ -44,10 +35,9 @@ async function eagerConnect(
|
|
|
44
35
|
params: {
|
|
45
36
|
getHub: () => Hub;
|
|
46
37
|
allBlockChains: UseAdapterParams['allBlockChains'];
|
|
47
|
-
onUpdateState?: EventHandler;
|
|
48
38
|
}
|
|
49
39
|
) {
|
|
50
|
-
const { getHub, allBlockChains
|
|
40
|
+
const { getHub, allBlockChains } = params;
|
|
51
41
|
const wallet = getHub().get(type);
|
|
52
42
|
if (!wallet) {
|
|
53
43
|
throw new Error(
|
|
@@ -82,7 +72,7 @@ async function eagerConnect(
|
|
|
82
72
|
: undefined;
|
|
83
73
|
const chain = evmChain || info.network;
|
|
84
74
|
|
|
85
|
-
return async ()
|
|
75
|
+
return async () => {
|
|
86
76
|
let connectNamespacePromise: () => Promise<
|
|
87
77
|
Accounts | AccountsWithActiveChain
|
|
88
78
|
>;
|
|
@@ -91,10 +81,19 @@ async function eagerConnect(
|
|
|
91
81
|
} else {
|
|
92
82
|
connectNamespacePromise = async () => namespace.connect();
|
|
93
83
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
84
|
+
try {
|
|
85
|
+
await connectNamespacePromise();
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
} catch (e: any) {
|
|
88
|
+
/*
|
|
89
|
+
* Since we check for connect failures using `instanceof Error`
|
|
90
|
+
* this check is added here to make sure the thrown error always is an instance of `Error`
|
|
91
|
+
*/
|
|
92
|
+
if (e instanceof Error) {
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
throw new Error(e);
|
|
96
|
+
}
|
|
98
97
|
};
|
|
99
98
|
}
|
|
100
99
|
);
|
|
@@ -104,31 +103,21 @@ async function eagerConnect(
|
|
|
104
103
|
* We are running a method at a time to make sure we are covering this.
|
|
105
104
|
* e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error.
|
|
106
105
|
*/
|
|
107
|
-
const
|
|
106
|
+
const connectNamespacesResult = await runSequentiallyWithoutFailure(
|
|
107
|
+
connectNamespacesPromises
|
|
108
|
+
);
|
|
108
109
|
|
|
109
|
-
const failedNamespaces =
|
|
110
|
-
.filter((
|
|
111
|
-
.map((
|
|
110
|
+
const failedNamespaces: NamespaceInputForConnect[] = targetNamespaces
|
|
111
|
+
.filter((_, index) => connectNamespacesResult[index].err)
|
|
112
|
+
.map((targetNamespace) => targetNamespace[0]);
|
|
112
113
|
|
|
113
114
|
if (failedNamespaces.length > 0) {
|
|
114
115
|
lastConnectedWalletsFromStorage.removeNamespacesFromWallet(
|
|
115
116
|
type,
|
|
116
|
-
failedNamespaces
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const autoConnectionAttemptError = buildAutoConnectionAttemptError(attempts);
|
|
121
|
-
if (autoConnectionAttemptError) {
|
|
122
|
-
onUpdateState?.(
|
|
123
|
-
type,
|
|
124
|
-
Events.AUTO_CONNECT_FAILED,
|
|
125
|
-
autoConnectionAttemptError,
|
|
126
|
-
getProviderCoreState(wallet),
|
|
127
|
-
getProviderEventInfo(wallet, allBlockChains)
|
|
117
|
+
failedNamespaces.map((namespace) => namespace.namespace)
|
|
128
118
|
);
|
|
129
119
|
}
|
|
130
120
|
|
|
131
|
-
const connectNamespacesResult = attempts.map(({ result }) => result);
|
|
132
121
|
const atLeastOneNamespaceConnectedSuccessfully = connectNamespacesResult.some(
|
|
133
122
|
(result) => result.ok
|
|
134
123
|
);
|
|
@@ -193,9 +182,8 @@ export async function autoConnect(deps: {
|
|
|
193
182
|
getHub: () => Hub;
|
|
194
183
|
allBlockChains: UseAdapterParams['allBlockChains'];
|
|
195
184
|
wallets?: (WalletType | Provider)[];
|
|
196
|
-
onUpdateState?: EventHandler;
|
|
197
185
|
}): Promise<void> {
|
|
198
|
-
const { getHub, allBlockChains, wallets
|
|
186
|
+
const { getHub, allBlockChains, wallets } = deps;
|
|
199
187
|
const lastConnectedWallets = lastConnectedWalletsFromStorage.list();
|
|
200
188
|
const walletIds = Object.keys(lastConnectedWallets);
|
|
201
189
|
|
|
@@ -247,7 +235,6 @@ export async function autoConnect(deps: {
|
|
|
247
235
|
eagerConnect(providerName, successNamespaces, {
|
|
248
236
|
allBlockChains,
|
|
249
237
|
getHub,
|
|
250
|
-
onUpdateState,
|
|
251
238
|
}).catch((error) => console.warn(error))
|
|
252
239
|
);
|
|
253
240
|
});
|
package/src/hub/helpers.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { AllProxiedNamespaces } from './types.js';
|
|
2
|
-
import type { NamespaceConnectAttempt } from '../errors.js';
|
|
3
|
-
import type { NamespaceInputForConnect } from '../legacy/types.js';
|
|
4
2
|
import type { ProviderProps } from '../types.js';
|
|
5
3
|
import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
|
|
6
|
-
import type {
|
|
4
|
+
import type { Result } from 'ts-results';
|
|
7
5
|
|
|
8
6
|
import {
|
|
9
7
|
CAIP_BITCOIN_CHAIN_ID,
|
|
@@ -16,9 +14,7 @@ import { CAIP_NAMESPACE as CAIP_TON_NAMESPACE } from '@hub3js/tvm';
|
|
|
16
14
|
import { formatAddressWithNetwork } from '@rango-dev/internal-blockchains';
|
|
17
15
|
import { CAIP_TRON_CHAIN_ID } from '@rango-dev/wallets-core/namespaces/tron';
|
|
18
16
|
import { AccountId, type ChainIdParams } from 'caip';
|
|
19
|
-
import { Err,
|
|
20
|
-
|
|
21
|
-
import { buildConnectionAttemptError } from '../errors.js';
|
|
17
|
+
import { Err, Ok } from 'ts-results';
|
|
22
18
|
|
|
23
19
|
export function mapCaipNamespaceToLegacyNetworkName(
|
|
24
20
|
chainId: ChainIdParams | string
|
|
@@ -73,23 +69,9 @@ export function fromAccountIdToLegacyAddressFormat(account: string): string {
|
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
/**
|
|
76
|
-
*
|
|
77
|
-
* order. The first failure rejects, and the promises after it don't run.
|
|
72
|
+
* Getting a list of (lazy) promises and run them one after another.
|
|
78
73
|
*/
|
|
79
|
-
export async function runSequentially<R>(
|
|
80
|
-
promises: Array<() => Promise<R>>
|
|
81
|
-
): Promise<R[]> {
|
|
82
|
-
const results: R[] = [];
|
|
83
|
-
for (const task of promises) {
|
|
84
|
-
results.push(await task());
|
|
85
|
-
}
|
|
86
|
-
return results;
|
|
87
|
-
}
|
|
88
74
|
|
|
89
|
-
/**
|
|
90
|
-
* Runs a list of (lazy) promises one after another, even when one fails, and returns
|
|
91
|
-
* each one's outcome in order as a `Result`.
|
|
92
|
-
*/
|
|
93
75
|
export async function runSequentiallyWithoutFailure<R>(
|
|
94
76
|
promises: Array<() => Promise<R>>
|
|
95
77
|
): Promise<Result<R, unknown>[]> {
|
|
@@ -116,18 +98,9 @@ export function isConnectResultSolana(
|
|
|
116
98
|
return Array.isArray(result);
|
|
117
99
|
}
|
|
118
100
|
|
|
119
|
-
export type QueueTaskResult<T> = {
|
|
120
|
-
result: Result<T, unknown>;
|
|
121
|
-
/*
|
|
122
|
-
* The task never ran: the queue abandoned it after an earlier task with the same key
|
|
123
|
-
* failed. `result` then holds that earlier failure.
|
|
124
|
-
*/
|
|
125
|
-
cancelled: boolean;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
101
|
type QueueItem<T> = {
|
|
129
102
|
task: () => Promise<T>;
|
|
130
|
-
resolve: (value:
|
|
103
|
+
resolve: (value: Result<T, unknown>) => void;
|
|
131
104
|
key: string;
|
|
132
105
|
};
|
|
133
106
|
/**
|
|
@@ -141,22 +114,22 @@ export function createQueue(options?: {
|
|
|
141
114
|
onError?: (
|
|
142
115
|
error: unknown,
|
|
143
116
|
actions: {
|
|
144
|
-
|
|
117
|
+
removeCurrentKeyFromQueue: () => void;
|
|
145
118
|
}
|
|
146
119
|
) => void;
|
|
147
120
|
}) {
|
|
148
121
|
const processingKeys = new Set<string>();
|
|
149
122
|
let queue: QueueItem<unknown>[] = [];
|
|
150
123
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
124
|
+
const removeKeyFromQueue = (
|
|
125
|
+
key: string,
|
|
126
|
+
result: Result<unknown, unknown>
|
|
154
127
|
) => {
|
|
155
128
|
queue = queue.filter((q) => {
|
|
156
|
-
if (q
|
|
129
|
+
if (q.key !== key) {
|
|
157
130
|
return true;
|
|
158
131
|
}
|
|
159
|
-
q.resolve(
|
|
132
|
+
q.resolve(result);
|
|
160
133
|
return false;
|
|
161
134
|
});
|
|
162
135
|
};
|
|
@@ -172,15 +145,16 @@ export function createQueue(options?: {
|
|
|
172
145
|
|
|
173
146
|
try {
|
|
174
147
|
const result = await task();
|
|
175
|
-
resolve(
|
|
148
|
+
resolve(new Ok(result));
|
|
176
149
|
} catch (error) {
|
|
177
150
|
if (options?.onError) {
|
|
178
151
|
options.onError(error, {
|
|
179
|
-
|
|
152
|
+
removeCurrentKeyFromQueue: () =>
|
|
153
|
+
removeKeyFromQueue(key, new Err(error)),
|
|
180
154
|
});
|
|
181
155
|
}
|
|
182
156
|
|
|
183
|
-
resolve(
|
|
157
|
+
resolve(new Err(error));
|
|
184
158
|
} finally {
|
|
185
159
|
const indexOfCurrentItem = queue.findIndex((item) => item.key === key);
|
|
186
160
|
if (indexOfCurrentItem >= 0) {
|
|
@@ -194,11 +168,11 @@ export function createQueue(options?: {
|
|
|
194
168
|
const queueTask = async <T>(
|
|
195
169
|
task: () => Promise<T>,
|
|
196
170
|
key: string
|
|
197
|
-
): Promise<
|
|
171
|
+
): Promise<Result<T, unknown>> =>
|
|
198
172
|
new Promise((resolve) => {
|
|
199
173
|
queue.push({
|
|
200
174
|
task,
|
|
201
|
-
resolve: resolve as (value:
|
|
175
|
+
resolve: resolve as (value: Result<unknown, unknown>) => void,
|
|
202
176
|
key,
|
|
203
177
|
});
|
|
204
178
|
void processQueue();
|
|
@@ -207,44 +181,6 @@ export function createQueue(options?: {
|
|
|
207
181
|
return queueTask;
|
|
208
182
|
}
|
|
209
183
|
|
|
210
|
-
/**
|
|
211
|
-
* Runs one `connect` attempt for the requested namespaces. `connectNamespaces` passes
|
|
212
|
-
* each namespace's attempt to `reportAttempts` once they have all settled. Anything it
|
|
213
|
-
* throws, such as a config error or saving to storage failing, is added after the
|
|
214
|
-
* namespace failures, unchanged.
|
|
215
|
-
*
|
|
216
|
-
* Throws a `WalletConnectionAttemptError` if anything failed; otherwise returns each
|
|
217
|
-
* namespace's result in request order.
|
|
218
|
-
*/
|
|
219
|
-
export async function runConnectionAttempt<T>(
|
|
220
|
-
namespaces: NamespaceInputForConnect[] | undefined,
|
|
221
|
-
connectNamespaces: (
|
|
222
|
-
reportAttempts: (attempts: NamespaceConnectAttempt<T>[]) => void
|
|
223
|
-
) => Promise<void>
|
|
224
|
-
): Promise<T[]> {
|
|
225
|
-
let attempts: NamespaceConnectAttempt<T>[] = [];
|
|
226
|
-
let nonNamespaceError: Option<unknown> = None;
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
await connectNamespaces((settledAttempts) => {
|
|
230
|
-
attempts = settledAttempts;
|
|
231
|
-
});
|
|
232
|
-
} catch (error) {
|
|
233
|
-
nonNamespaceError = new Some(error);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const attemptError = buildConnectionAttemptError({
|
|
237
|
-
requestedNamespaces: namespaces ?? [],
|
|
238
|
-
attempts,
|
|
239
|
-
nonNamespaceError,
|
|
240
|
-
});
|
|
241
|
-
if (attemptError) {
|
|
242
|
-
throw attemptError;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return attempts.map(({ result }) => result.unwrap());
|
|
246
|
-
}
|
|
247
|
-
|
|
248
184
|
export function shouldTryAutoConnect(
|
|
249
185
|
props: Pick<ProviderProps, 'allBlockChains' | 'autoConnect'>
|
|
250
186
|
): boolean {
|
package/src/hub/useHubAdapter.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { AllProxiedNamespaces, ExtensionLink } from './types.js';
|
|
2
|
-
import type { NamespaceConnectAttempt } from '../errors.js';
|
|
3
2
|
import type {
|
|
4
3
|
ConnectResult,
|
|
5
4
|
NamespaceInputForConnect,
|
|
@@ -9,22 +8,19 @@ import type { ProviderContext, ProviderProps } from '../types.js';
|
|
|
9
8
|
import type { Provider, WalletType } from '@hub3js/core';
|
|
10
9
|
import type { Accounts, AccountsWithActiveChain } from '@hub3js/std/types';
|
|
11
10
|
|
|
12
|
-
import { isUserRejectionError } from '@hub3js/std/utils';
|
|
11
|
+
import { isUserRejectionError, WalletConnectionError } from '@hub3js/std/utils';
|
|
13
12
|
import {
|
|
14
13
|
getSupportedChainsFromNamespace,
|
|
15
14
|
getSupportedChainsFromProvider,
|
|
16
15
|
} from '@rango-dev/internal-blockchains';
|
|
17
16
|
import { useEffect, useRef, useState } from 'react';
|
|
17
|
+
import { Ok, Result } from 'ts-results';
|
|
18
18
|
|
|
19
19
|
import { withErrorLoggingApi } from '../helpers.js';
|
|
20
20
|
|
|
21
21
|
import { autoConnect } from './autoConnect.js';
|
|
22
22
|
import { HUB_LAST_CONNECTED_WALLETS } from './constants.js';
|
|
23
|
-
import {
|
|
24
|
-
createQueue,
|
|
25
|
-
fromAccountIdToLegacyAddressFormat,
|
|
26
|
-
runConnectionAttempt,
|
|
27
|
-
} from './helpers.js';
|
|
23
|
+
import { createQueue, fromAccountIdToLegacyAddressFormat } from './helpers.js';
|
|
28
24
|
import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js';
|
|
29
25
|
import { useAutoConnect } from './useAutoConnect.js';
|
|
30
26
|
import { useHubRefs } from './useHubRefs.js';
|
|
@@ -69,8 +65,11 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
69
65
|
|
|
70
66
|
const queueTask = createQueue({
|
|
71
67
|
onError: (error, actions) => {
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
// A connection failure carries the wallet's own error, and so its code, as its cause.
|
|
69
|
+
const walletError =
|
|
70
|
+
error instanceof WalletConnectionError ? error.cause : error;
|
|
71
|
+
if (isUserRejectionError(walletError)) {
|
|
72
|
+
actions.removeCurrentKeyFromQueue();
|
|
74
73
|
}
|
|
75
74
|
},
|
|
76
75
|
});
|
|
@@ -124,7 +123,6 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
124
123
|
allBlockChains: params.allBlockChains,
|
|
125
124
|
getHub,
|
|
126
125
|
wallets: params.configs?.wallets,
|
|
127
|
-
onUpdateState: params.onUpdateState,
|
|
128
126
|
});
|
|
129
127
|
},
|
|
130
128
|
});
|
|
@@ -188,117 +186,121 @@ export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
|
188
186
|
});
|
|
189
187
|
},
|
|
190
188
|
async connect(type, namespaces) {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
189
|
+
const wallet = getHub().get(type);
|
|
190
|
+
if (!wallet) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
`You should add ${type} to provider first then call 'connect'.`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!namespaces) {
|
|
197
|
+
throw new Error('Passing namespace to `connect` is required.');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
updateLastConnectAttemptParams(type, namespaces);
|
|
201
|
+
|
|
202
|
+
// Check `namespace` and look into hub to see how it can match given namespace to hub namespace.
|
|
203
|
+
const targetNamespaces: [
|
|
204
|
+
NamespaceInputForConnect,
|
|
205
|
+
AllProxiedNamespaces
|
|
206
|
+
][] = [];
|
|
207
|
+
namespaces.forEach((namespace) => {
|
|
208
|
+
const targetNamespace = namespace.namespace;
|
|
209
|
+
|
|
210
|
+
const result = wallet.findByNamespace(targetNamespace);
|
|
211
|
+
if (!result) {
|
|
198
212
|
throw new Error(
|
|
199
|
-
`
|
|
213
|
+
`We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`
|
|
200
214
|
);
|
|
201
215
|
}
|
|
202
216
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
217
|
+
targetNamespaces.push([namespace, result]);
|
|
218
|
+
});
|
|
206
219
|
|
|
207
|
-
|
|
220
|
+
// Try to run `connect` on matched namespaces
|
|
221
|
+
const connectResultFromTargetNamespaces = targetNamespaces.map(
|
|
222
|
+
async ([namespaceInput, namespace]) => {
|
|
223
|
+
const network = tryConvertNamespaceNetworkToChainInfo(
|
|
224
|
+
namespaceInput,
|
|
225
|
+
params.allBlockChains || []
|
|
226
|
+
);
|
|
208
227
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
AllProxiedNamespaces
|
|
213
|
-
][] = [];
|
|
214
|
-
namespaces.forEach((namespace) => {
|
|
215
|
-
const targetNamespace = namespace.namespace;
|
|
228
|
+
let connectNamespacePromise: () => Promise<
|
|
229
|
+
Accounts | AccountsWithActiveChain
|
|
230
|
+
>;
|
|
216
231
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
232
|
+
if (isSolanaNamespace(namespace)) {
|
|
233
|
+
connectNamespacePromise = async () =>
|
|
234
|
+
namespace.connect({
|
|
235
|
+
derivationPath: namespaceInput.derivationPath,
|
|
236
|
+
});
|
|
237
|
+
} else if (isEvmNamespace(namespace)) {
|
|
238
|
+
connectNamespacePromise = async () =>
|
|
239
|
+
namespace.connect(network, {
|
|
240
|
+
derivationPath: namespaceInput.derivationPath,
|
|
241
|
+
});
|
|
242
|
+
} else if (isUtxoNamespace(namespace)) {
|
|
243
|
+
connectNamespacePromise = async () =>
|
|
244
|
+
namespace.connect({
|
|
245
|
+
derivationPath: namespaceInput.derivationPath,
|
|
246
|
+
});
|
|
247
|
+
} else {
|
|
248
|
+
connectNamespacePromise = async () => namespace.connect();
|
|
222
249
|
}
|
|
223
250
|
|
|
224
|
-
|
|
225
|
-
|
|
251
|
+
const connectNamespaceProcess = async () =>
|
|
252
|
+
connectNamespacePromise()
|
|
253
|
+
.then<ConnectResult>(transformHubResultToLegacyResult)
|
|
254
|
+
.then((connectResult) => {
|
|
255
|
+
return {
|
|
256
|
+
response: connectResult,
|
|
257
|
+
input: {
|
|
258
|
+
namespace: namespaceInput.namespace,
|
|
259
|
+
network: namespaceInput.network,
|
|
260
|
+
supportsEagerConnect: 'canEagerConnect' in namespace,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
return queueTask(connectNamespaceProcess, type);
|
|
265
|
+
}
|
|
266
|
+
);
|
|
226
267
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
268
|
+
/*
|
|
269
|
+
* We need to connect to namespace one after another, sending multiple requests at the same time may be failed.
|
|
270
|
+
* e.g. when wallet popup opens and asking for the password from the user, it should be resolved first, then other request will be resolved.
|
|
271
|
+
*/
|
|
272
|
+
const connectResultWithLegacyFormat = await Promise.all(
|
|
273
|
+
connectResultFromTargetNamespaces
|
|
274
|
+
);
|
|
234
275
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
} else if (isUtxoNamespace(namespace)) {
|
|
250
|
-
connectNamespacePromise = async () =>
|
|
251
|
-
namespace.connect({
|
|
252
|
-
derivationPath: namespaceInput.derivationPath,
|
|
253
|
-
});
|
|
254
|
-
} else {
|
|
255
|
-
connectNamespacePromise = async () => namespace.connect();
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const connectNamespaceProcess = async () =>
|
|
259
|
-
connectNamespacePromise().then<ConnectResult>(
|
|
260
|
-
transformHubResultToLegacyResult
|
|
261
|
-
);
|
|
262
|
-
const { result, cancelled } = await queueTask(
|
|
263
|
-
connectNamespaceProcess,
|
|
264
|
-
type
|
|
265
|
-
);
|
|
266
|
-
return {
|
|
267
|
-
input: namespaceInput,
|
|
268
|
-
result,
|
|
269
|
-
cancelled,
|
|
270
|
-
supportsEagerConnect: 'canEagerConnect' in namespace,
|
|
271
|
-
};
|
|
272
|
-
}
|
|
276
|
+
// Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.
|
|
277
|
+
const successfullyConnectedSupportingEagerConnectNamespaces =
|
|
278
|
+
connectResultWithLegacyFormat
|
|
279
|
+
.filter(<T, E>(result: Result<T, E>): result is Ok<T> => result.ok)
|
|
280
|
+
.filter((result) => result.val.input.supportsEagerConnect)
|
|
281
|
+
.map((result) => ({
|
|
282
|
+
namespace: result.val.input.namespace,
|
|
283
|
+
network: result.val.input.network,
|
|
284
|
+
}));
|
|
285
|
+
|
|
286
|
+
if (successfullyConnectedSupportingEagerConnectNamespaces.length > 0) {
|
|
287
|
+
lastConnectedWalletsFromStorage.addWallet(
|
|
288
|
+
type,
|
|
289
|
+
successfullyConnectedSupportingEagerConnectNamespaces
|
|
273
290
|
);
|
|
291
|
+
}
|
|
274
292
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const attempts = await Promise.all(connectAttemptsFromTargetNamespaces);
|
|
280
|
-
reportAttempts(attempts);
|
|
281
|
-
|
|
282
|
-
// Keeping only namespaces that connected successfully and support eager connect, then we'll store them on storage for auto connect functionality.
|
|
283
|
-
const successfullyConnectedSupportingEagerConnectNamespaces = attempts
|
|
284
|
-
.filter(
|
|
285
|
-
({ result, supportsEagerConnect }) =>
|
|
286
|
-
result.ok && supportsEagerConnect
|
|
287
|
-
)
|
|
288
|
-
.map(({ input }) => ({
|
|
289
|
-
namespace: input.namespace,
|
|
290
|
-
network: input.network,
|
|
291
|
-
}));
|
|
293
|
+
// Getting rid of `input` from Result
|
|
294
|
+
const connectResults = connectResultWithLegacyFormat.map((result) =>
|
|
295
|
+
result.andThen((okResult) => new Ok(okResult.response))
|
|
296
|
+
);
|
|
292
297
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
};
|
|
298
|
+
const allResult = Result.all(...connectResults);
|
|
299
|
+
if (allResult.err) {
|
|
300
|
+
throw allResult.val;
|
|
301
|
+
}
|
|
300
302
|
|
|
301
|
-
return
|
|
303
|
+
return allResult.unwrap();
|
|
302
304
|
},
|
|
303
305
|
async disconnect(type, namespaces) {
|
|
304
306
|
const wallet = getHub().get(type);
|
package/src/hub/utils.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { AllProxiedNamespaces } from './types.js';
|
|
2
2
|
import type {
|
|
3
3
|
ConnectResult,
|
|
4
|
-
EventInfo,
|
|
5
4
|
NamespaceInputForConnect,
|
|
6
5
|
EventHandler as WalletEventHandler,
|
|
7
|
-
WalletState,
|
|
8
6
|
} from '../legacy/mod.js';
|
|
9
7
|
import type { ProviderProps } from '../types.js';
|
|
10
8
|
import type { UtxoActions } from '@hub3js/bip122';
|
|
@@ -55,38 +53,6 @@ export function findProviderByType(
|
|
|
55
53
|
return providers.find((provider) => provider.id === type);
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
// The legacy wallet state sent with an event, before any namespace-specific fields.
|
|
59
|
-
export function getProviderCoreState(provider: Provider): WalletState {
|
|
60
|
-
const [getProviderState] = provider.state();
|
|
61
|
-
return {
|
|
62
|
-
connected: getProviderState().connected,
|
|
63
|
-
connecting: getProviderState().connecting,
|
|
64
|
-
installed: getProviderState().installed,
|
|
65
|
-
accounts: null,
|
|
66
|
-
network: null,
|
|
67
|
-
reachable: true,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// The legacy event info sent with an event, before any namespace-specific fields.
|
|
72
|
-
export function getProviderEventInfo(
|
|
73
|
-
provider: Provider,
|
|
74
|
-
allBlockChains: ProviderProps['allBlockChains']
|
|
75
|
-
): EventInfo {
|
|
76
|
-
const detailsProperty = provider
|
|
77
|
-
.info()
|
|
78
|
-
?.metadata.properties?.find((property) => property.name === 'details');
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
supportedBlockchains: getSupportedChainsFromProvider(
|
|
82
|
-
provider,
|
|
83
|
-
allBlockChains
|
|
84
|
-
),
|
|
85
|
-
isContractWallet: detailsProperty?.value?.isContractWallet ?? false,
|
|
86
|
-
isHub: true,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
56
|
/**
|
|
91
57
|
* We will call this function on hub's `subscribe`.
|
|
92
58
|
* it will check states and will emit legacy events for backward compatibility.
|
|
@@ -139,15 +105,28 @@ export function mapHubEventsToLegacy(
|
|
|
139
105
|
}
|
|
140
106
|
}
|
|
141
107
|
|
|
108
|
+
const [getProviderState] = provider.state();
|
|
142
109
|
const coreState = {
|
|
143
|
-
|
|
110
|
+
connected: getProviderState().connected,
|
|
111
|
+
connecting: getProviderState().connecting,
|
|
112
|
+
installed: getProviderState().installed,
|
|
144
113
|
accounts,
|
|
145
114
|
network,
|
|
115
|
+
reachable: true,
|
|
146
116
|
derivationPath,
|
|
147
117
|
};
|
|
148
118
|
|
|
119
|
+
const detailsProperty = provider
|
|
120
|
+
.info()
|
|
121
|
+
?.metadata.properties?.find((property) => property.name === 'details');
|
|
122
|
+
|
|
149
123
|
const eventInfo = {
|
|
150
|
-
|
|
124
|
+
supportedBlockchains: getSupportedChainsFromProvider(
|
|
125
|
+
provider,
|
|
126
|
+
metadata.allBlockChains
|
|
127
|
+
),
|
|
128
|
+
isContractWallet: detailsProperty?.value?.isContractWallet ?? false,
|
|
129
|
+
isHub: true,
|
|
151
130
|
namespace: namespaceId,
|
|
152
131
|
};
|
|
153
132
|
|
package/src/index.ts
CHANGED
package/src/legacy/types.ts
CHANGED
|
@@ -78,11 +78,6 @@ export enum Events {
|
|
|
78
78
|
NAMESPACE_DISCONNECTED = 'namespace_disconnected',
|
|
79
79
|
|
|
80
80
|
PROVIDER_DISCONNECTED = 'provider_disconnected',
|
|
81
|
-
/**
|
|
82
|
-
* Internal: auto-connect couldn't connect one or more namespaces of a wallet.
|
|
83
|
-
* The value is an `AutoConnectionAttemptError`.
|
|
84
|
-
*/
|
|
85
|
-
AUTO_CONNECT_FAILED = 'auto_connect_failed',
|
|
86
81
|
}
|
|
87
82
|
|
|
88
83
|
export type EventInfo = {
|