@rango-dev/wallets-react 0.0.0-experimental-936229e8-20251208
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/CHANGELOG.md +265 -0
- package/dist/helpers/index.d.ts +2 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +2 -0
- package/dist/helpers/index.js.map +7 -0
- package/dist/hub/autoConnect.d.ts +11 -0
- package/dist/hub/autoConnect.d.ts.map +1 -0
- package/dist/hub/constants.d.ts +3 -0
- package/dist/hub/constants.d.ts.map +1 -0
- package/dist/hub/helpers.d.ts +33 -0
- package/dist/hub/helpers.d.ts.map +1 -0
- package/dist/hub/lastConnectedWallets.d.ts +22 -0
- package/dist/hub/lastConnectedWallets.d.ts.map +1 -0
- package/dist/hub/mod.d.ts +3 -0
- package/dist/hub/mod.d.ts.map +1 -0
- package/dist/hub/types.d.ts +4 -0
- package/dist/hub/types.d.ts.map +1 -0
- package/dist/hub/useHubAdapter.d.ts +11 -0
- package/dist/hub/useHubAdapter.d.ts.map +1 -0
- package/dist/hub/useHubRefs.d.ts +7 -0
- package/dist/hub/useHubRefs.d.ts.map +1 -0
- package/dist/hub/utils.d.ts +52 -0
- package/dist/hub/utils.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/legacy/autoConnect.d.ts +8 -0
- package/dist/legacy/autoConnect.d.ts.map +1 -0
- package/dist/legacy/context.d.ts +3 -0
- package/dist/legacy/context.d.ts.map +1 -0
- package/dist/legacy/helpers.d.ts +23 -0
- package/dist/legacy/helpers.d.ts.map +1 -0
- package/dist/legacy/hooks.d.ts +10 -0
- package/dist/legacy/hooks.d.ts.map +1 -0
- package/dist/legacy/mod.d.ts +5 -0
- package/dist/legacy/mod.d.ts.map +1 -0
- package/dist/legacy/types.d.ts +143 -0
- package/dist/legacy/types.d.ts.map +1 -0
- package/dist/legacy/useAutoConnect.d.ts +8 -0
- package/dist/legacy/useAutoConnect.d.ts.map +1 -0
- package/dist/legacy/useLegacyProviders.d.ts +7 -0
- package/dist/legacy/useLegacyProviders.d.ts.map +1 -0
- package/dist/legacy/utils.d.ts +3 -0
- package/dist/legacy/utils.d.ts.map +1 -0
- package/dist/provider.d.ts +5 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/test-utils/env.d.ts +7 -0
- package/dist/test-utils/env.d.ts.map +1 -0
- package/dist/test-utils/fixtures.d.ts +14 -0
- package/dist/test-utils/fixtures.d.ts.map +1 -0
- package/dist/useProviders.d.ts +4 -0
- package/dist/useProviders.d.ts.map +1 -0
- package/dist/wallets-react.build.json +1 -0
- package/helpers/package.json +8 -0
- package/package.json +50 -0
- package/readme.md +3 -0
- package/src/helpers/index.ts +1 -0
- package/src/hub/autoConnect.ts +276 -0
- package/src/hub/constants.ts +2 -0
- package/src/hub/helpers.ts +179 -0
- package/src/hub/lastConnectedWallets.ts +166 -0
- package/src/hub/mod.ts +6 -0
- package/src/hub/types.ts +12 -0
- package/src/hub/useHubAdapter.ts +516 -0
- package/src/hub/useHubRefs.ts +50 -0
- package/src/hub/utils.ts +393 -0
- package/src/index.ts +4 -0
- package/src/legacy/autoConnect.ts +66 -0
- package/src/legacy/context.ts +39 -0
- package/src/legacy/helpers.ts +183 -0
- package/src/legacy/hooks.ts +54 -0
- package/src/legacy/mod.ts +13 -0
- package/src/legacy/types.ts +195 -0
- package/src/legacy/useAutoConnect.ts +23 -0
- package/src/legacy/useLegacyProviders.ts +241 -0
- package/src/legacy/utils.ts +7 -0
- package/src/provider.tsx +18 -0
- package/src/test-utils/env.ts +10 -0
- package/src/test-utils/fixtures.ts +238 -0
- package/src/useProviders.ts +120 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type { AllProxiedNamespaces } from './types.js';
|
|
2
|
+
import type {
|
|
3
|
+
Accounts,
|
|
4
|
+
AccountsWithActiveChain,
|
|
5
|
+
} from '@rango-dev/wallets-core/namespaces/common';
|
|
6
|
+
import type { BlockchainMeta } from 'rango-types';
|
|
7
|
+
import type { Result } from 'ts-results';
|
|
8
|
+
|
|
9
|
+
import { legacyFormatAddressWithNetwork as formatAddressWithNetwork } from '@rango-dev/wallets-core/legacy';
|
|
10
|
+
import { CAIP_NAMESPACE as CAIP_COSMOS_NAMESPACE } from '@rango-dev/wallets-core/namespaces/cosmos';
|
|
11
|
+
import { CAIP_TRON_CHAIN_ID } from '@rango-dev/wallets-core/namespaces/tron';
|
|
12
|
+
import { CAIP_BITCOIN_CHAIN_ID } from '@rango-dev/wallets-core/namespaces/utxo';
|
|
13
|
+
import { CAIP } from '@rango-dev/wallets-core/utils';
|
|
14
|
+
import { getBlockChainNameFromId } from '@rango-dev/wallets-shared';
|
|
15
|
+
import { Err, Ok } from 'ts-results';
|
|
16
|
+
|
|
17
|
+
export function mapCaipNamespaceToLegacyNetworkName(
|
|
18
|
+
chainId: CAIP.ChainIdParams | string,
|
|
19
|
+
allBlockChains: BlockchainMeta[]
|
|
20
|
+
): string {
|
|
21
|
+
if (typeof chainId === 'string') {
|
|
22
|
+
return chainId;
|
|
23
|
+
}
|
|
24
|
+
const useNamespaceAsNetworkFor = ['solana'];
|
|
25
|
+
|
|
26
|
+
if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) {
|
|
27
|
+
return chainId.namespace.toUpperCase();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (chainId.namespace.toLowerCase() === 'eip155') {
|
|
31
|
+
return 'ETH';
|
|
32
|
+
} else if (chainId.reference === CAIP_BITCOIN_CHAIN_ID) {
|
|
33
|
+
return 'BTC';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (chainId.namespace.toLowerCase() === CAIP_COSMOS_NAMESPACE) {
|
|
37
|
+
const network = getBlockChainNameFromId(chainId.reference, allBlockChains);
|
|
38
|
+
if (!network) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Network didn't found for given chainId: ${chainId.reference}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return network;
|
|
44
|
+
}
|
|
45
|
+
if (chainId.namespace === 'sui' || chainId.reference === CAIP_TRON_CHAIN_ID) {
|
|
46
|
+
return chainId.reference.toUpperCase();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return chainId.reference;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb
|
|
54
|
+
* Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb
|
|
55
|
+
* This function will try to convert this two format.
|
|
56
|
+
*
|
|
57
|
+
* @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md
|
|
58
|
+
*/
|
|
59
|
+
export function fromAccountIdToLegacyAddressFormat(
|
|
60
|
+
account: string,
|
|
61
|
+
allBlockChains: BlockchainMeta[]
|
|
62
|
+
): string {
|
|
63
|
+
const { chainId, address } = CAIP.AccountId.parse(account);
|
|
64
|
+
const network = mapCaipNamespaceToLegacyNetworkName(chainId, allBlockChains);
|
|
65
|
+
return formatAddressWithNetwork(address, network);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Getting a list of (lazy) promises and run them one after another.
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
export async function runSequentiallyWithoutFailure<R>(
|
|
73
|
+
promises: Array<() => Promise<R>>
|
|
74
|
+
): Promise<Result<R, unknown>[]> {
|
|
75
|
+
return promises.reduce(async (prevPromise, task) => {
|
|
76
|
+
const previousResults = await prevPromise;
|
|
77
|
+
try {
|
|
78
|
+
const taskResult = await task();
|
|
79
|
+
return [...previousResults, new Ok(taskResult)];
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return [...previousResults, new Err(error)];
|
|
82
|
+
}
|
|
83
|
+
}, Promise.resolve<Result<R, unknown>[]>([]));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function isConnectResultEvm(
|
|
87
|
+
result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>
|
|
88
|
+
): result is AccountsWithActiveChain {
|
|
89
|
+
return typeof result === 'object' && !Array.isArray(result);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function isConnectResultSolana(
|
|
93
|
+
result: Awaited<ReturnType<AllProxiedNamespaces['connect']>>
|
|
94
|
+
): result is Accounts {
|
|
95
|
+
return Array.isArray(result);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type QueueItem<T> = {
|
|
99
|
+
task: () => Promise<T>;
|
|
100
|
+
resolve: (value: Result<T, unknown>) => void;
|
|
101
|
+
key: string;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Creates a queue manager that ensures sequential execution of tasks by key.
|
|
105
|
+
* When multiple tasks with the same key are queued, they are executed one at a time
|
|
106
|
+
* in the order they were added. This prevents race conditions and ensures
|
|
107
|
+
* predictable task execution order.
|
|
108
|
+
*
|
|
109
|
+
*/
|
|
110
|
+
export function createQueue(options?: {
|
|
111
|
+
onError?: (
|
|
112
|
+
error: unknown,
|
|
113
|
+
actions: {
|
|
114
|
+
removeCurrentKeyFromQueue: () => void;
|
|
115
|
+
}
|
|
116
|
+
) => void;
|
|
117
|
+
}) {
|
|
118
|
+
const processingKeys = new Set<string>();
|
|
119
|
+
let queue: QueueItem<unknown>[] = [];
|
|
120
|
+
|
|
121
|
+
const removeKeyFromQueue = (
|
|
122
|
+
key: string,
|
|
123
|
+
result: Result<unknown, unknown>
|
|
124
|
+
) => {
|
|
125
|
+
queue = queue.filter((q) => {
|
|
126
|
+
if (q.key !== key) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
q.resolve(result);
|
|
130
|
+
return false;
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const processQueue = async () => {
|
|
135
|
+
const currentItem = queue.find((item) => !processingKeys.has(item.key));
|
|
136
|
+
if (!currentItem) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const { task, resolve, key } = currentItem;
|
|
141
|
+
processingKeys.add(key);
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const result = await task();
|
|
145
|
+
resolve(new Ok(result));
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (options?.onError) {
|
|
148
|
+
options.onError(error, {
|
|
149
|
+
removeCurrentKeyFromQueue: () =>
|
|
150
|
+
removeKeyFromQueue(key, new Err(error)),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
resolve(new Err(error));
|
|
155
|
+
} finally {
|
|
156
|
+
const indexOfCurrentItem = queue.findIndex((item) => item.key === key);
|
|
157
|
+
if (indexOfCurrentItem >= 0) {
|
|
158
|
+
queue.splice(indexOfCurrentItem, 1);
|
|
159
|
+
}
|
|
160
|
+
processingKeys.delete(key);
|
|
161
|
+
void processQueue();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const queueTask = async <T>(
|
|
166
|
+
task: () => Promise<T>,
|
|
167
|
+
key: string
|
|
168
|
+
): Promise<Result<T, unknown>> =>
|
|
169
|
+
new Promise((resolve) => {
|
|
170
|
+
queue.push({
|
|
171
|
+
task,
|
|
172
|
+
resolve: resolve as (value: Result<unknown, unknown>) => void,
|
|
173
|
+
key,
|
|
174
|
+
});
|
|
175
|
+
void processQueue();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
return queueTask;
|
|
179
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { Namespace } from '@rango-dev/wallets-core/namespaces/common';
|
|
2
|
+
|
|
3
|
+
import { Persistor } from '@rango-dev/wallets-core/legacy';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
HUB_LAST_CONNECTED_WALLETS,
|
|
7
|
+
LEGACY_LAST_CONNECTED_WALLETS,
|
|
8
|
+
} from './constants.js';
|
|
9
|
+
|
|
10
|
+
export interface NamespaceInput {
|
|
11
|
+
namespace: Namespace;
|
|
12
|
+
network: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface LastConnectedWalletsStorage {
|
|
16
|
+
[providerId: string]: NamespaceInput[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type LegacyLastConnectedWalletsStorage = string[];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* We are doing some certain actions on storage for `last-connected-wallets` key.
|
|
23
|
+
* This class helps us to define them in one place and also it has support for both legacy and hub.
|
|
24
|
+
*/
|
|
25
|
+
export class LastConnectedWalletsFromStorage {
|
|
26
|
+
#storageKey: string;
|
|
27
|
+
|
|
28
|
+
constructor(storageKey: string) {
|
|
29
|
+
this.#storageKey = storageKey;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
addWallet(providerId: string, namespaces: NamespaceInput[]): void {
|
|
33
|
+
if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {
|
|
34
|
+
return this.#addWalletToHub(providerId, namespaces);
|
|
35
|
+
} else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {
|
|
36
|
+
return this.#addWalletToLegacy(providerId);
|
|
37
|
+
}
|
|
38
|
+
throw new Error('Not implemented');
|
|
39
|
+
}
|
|
40
|
+
removeWallets(providerIds?: string[]): void {
|
|
41
|
+
if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {
|
|
42
|
+
return this.#removeWalletsFromHub(providerIds);
|
|
43
|
+
} else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {
|
|
44
|
+
return this.#removeWalletsFromLegacy(providerIds);
|
|
45
|
+
}
|
|
46
|
+
throw new Error('Not implemented');
|
|
47
|
+
}
|
|
48
|
+
list(): LastConnectedWalletsStorage {
|
|
49
|
+
if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {
|
|
50
|
+
return this.#listFromHub();
|
|
51
|
+
} else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) {
|
|
52
|
+
return this.#listFromLegacy();
|
|
53
|
+
}
|
|
54
|
+
throw new Error('Not implemented');
|
|
55
|
+
}
|
|
56
|
+
removeNamespacesFromWallet(providerId: string, namespaceIds: string[]) {
|
|
57
|
+
if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) {
|
|
58
|
+
return this.#removeNamespaceFromWalletHub(providerId, namespaceIds);
|
|
59
|
+
}
|
|
60
|
+
throw new Error('Not implemented');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#listFromLegacy(): LastConnectedWalletsStorage {
|
|
64
|
+
const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
65
|
+
const lastConnectedWallets =
|
|
66
|
+
persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS) || [];
|
|
67
|
+
const output: LastConnectedWalletsStorage = {};
|
|
68
|
+
lastConnectedWallets.forEach((provider) => {
|
|
69
|
+
// Setting empty namespaces
|
|
70
|
+
output[provider] = [];
|
|
71
|
+
});
|
|
72
|
+
return output;
|
|
73
|
+
}
|
|
74
|
+
#listFromHub(): LastConnectedWalletsStorage {
|
|
75
|
+
const persistor = new Persistor<LastConnectedWalletsStorage>();
|
|
76
|
+
const lastConnectedWallets =
|
|
77
|
+
persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};
|
|
78
|
+
return lastConnectedWallets;
|
|
79
|
+
}
|
|
80
|
+
#addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {
|
|
81
|
+
const storage = new Persistor<LastConnectedWalletsStorage>();
|
|
82
|
+
const storageState = storage.getItem(this.#storageKey) || {};
|
|
83
|
+
|
|
84
|
+
let toBeAddedNamespaces = namespaces;
|
|
85
|
+
|
|
86
|
+
// If provider already exits in the storage, we should just add new namespaces to the previously added namespaces.
|
|
87
|
+
if (!!storageState[providerId]) {
|
|
88
|
+
const storedNamespaces = storageState[providerId];
|
|
89
|
+
toBeAddedNamespaces = storedNamespaces.concat(
|
|
90
|
+
namespaces.filter(
|
|
91
|
+
(namespace) =>
|
|
92
|
+
!storedNamespaces.some(
|
|
93
|
+
(storedNamespace) =>
|
|
94
|
+
storedNamespace.namespace === namespace.namespace
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
storage.setItem(this.#storageKey, {
|
|
101
|
+
...storageState,
|
|
102
|
+
[providerId]: toBeAddedNamespaces,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
#addWalletToLegacy(providerId: string): void {
|
|
106
|
+
const storage = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
107
|
+
const storageState = storage.getItem(this.#storageKey) || [];
|
|
108
|
+
|
|
109
|
+
storage.setItem(
|
|
110
|
+
LEGACY_LAST_CONNECTED_WALLETS,
|
|
111
|
+
storageState.concat(providerId)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
#removeWalletsFromHub(providerIds?: string[]): void {
|
|
115
|
+
const persistor = new Persistor<LastConnectedWalletsStorage>();
|
|
116
|
+
const storageState = persistor.getItem(this.#storageKey) || {};
|
|
117
|
+
|
|
118
|
+
// Remove all wallets
|
|
119
|
+
if (!providerIds) {
|
|
120
|
+
persistor.setItem(this.#storageKey, {});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Remove some of the wallets
|
|
125
|
+
providerIds.forEach((providerId) => {
|
|
126
|
+
if (storageState[providerId]) {
|
|
127
|
+
delete storageState[providerId];
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
persistor.setItem(this.#storageKey, storageState);
|
|
132
|
+
}
|
|
133
|
+
#removeNamespaceFromWalletHub(
|
|
134
|
+
providerId: string,
|
|
135
|
+
namespaceIds: string[]
|
|
136
|
+
): void {
|
|
137
|
+
const persistor = new Persistor<LastConnectedWalletsStorage>();
|
|
138
|
+
const storageState = persistor.getItem(this.#storageKey) || {};
|
|
139
|
+
|
|
140
|
+
const currentProviderNamespaces = storageState[providerId];
|
|
141
|
+
const newProviderNamespaces = currentProviderNamespaces?.filter(
|
|
142
|
+
(namespace) => !namespaceIds.includes(namespace.namespace)
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
this.#removeWalletsFromHub([providerId]);
|
|
146
|
+
if (newProviderNamespaces?.length > 0) {
|
|
147
|
+
this.#addWalletToHub(providerId, newProviderNamespaces);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
#removeWalletsFromLegacy(providerIds?: string[]): void {
|
|
151
|
+
const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
152
|
+
const storageState = persistor.getItem(this.#storageKey) || [];
|
|
153
|
+
|
|
154
|
+
// Remove all wallets
|
|
155
|
+
if (!providerIds) {
|
|
156
|
+
persistor.setItem(this.#storageKey, []);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Remove some of the wallets
|
|
161
|
+
persistor.setItem(
|
|
162
|
+
LEGACY_LAST_CONNECTED_WALLETS,
|
|
163
|
+
storageState.filter((wallet) => !providerIds.includes(wallet))
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/hub/mod.ts
ADDED
package/src/hub/types.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CommonNamespaces,
|
|
3
|
+
FindProxiedNamespace,
|
|
4
|
+
ProviderMetadata,
|
|
5
|
+
} from '@rango-dev/wallets-core';
|
|
6
|
+
|
|
7
|
+
export type AllProxiedNamespaces = FindProxiedNamespace<
|
|
8
|
+
keyof CommonNamespaces,
|
|
9
|
+
CommonNamespaces
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
export type ExtensionLink = keyof ProviderMetadata['extensions'];
|