@rango-dev/wallets-react 0.27.0 → 0.27.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.
- package/CHANGELOG.md +4 -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 +19 -0
- package/dist/hub/helpers.d.ts.map +1 -0
- package/dist/hub/lastConnectedWallets.d.ts +21 -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 +10 -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 +32 -0
- package/dist/hub/utils.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/legacy/autoConnect.d.ts +8 -0
- package/dist/legacy/autoConnect.d.ts.map +1 -0
- package/dist/legacy/helpers.d.ts +2 -6
- package/dist/legacy/helpers.d.ts.map +1 -1
- package/dist/legacy/mod.d.ts +5 -0
- package/dist/legacy/mod.d.ts.map +1 -0
- package/dist/legacy/types.d.ts +13 -4
- package/dist/legacy/types.d.ts.map +1 -1
- package/dist/legacy/useAutoConnect.d.ts +5 -4
- package/dist/legacy/useAutoConnect.d.ts.map +1 -1
- package/dist/legacy/useLegacyProviders.d.ts +5 -1
- package/dist/legacy/useLegacyProviders.d.ts.map +1 -1
- package/dist/legacy/utils.d.ts +3 -0
- package/dist/legacy/utils.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 -1
- package/package.json +14 -6
- package/src/hub/autoConnect.ts +186 -0
- package/src/hub/constants.ts +2 -0
- package/src/hub/helpers.ts +67 -0
- package/src/hub/lastConnectedWallets.ts +124 -0
- package/src/hub/mod.ts +2 -0
- package/src/hub/types.ts +12 -0
- package/src/hub/useHubAdapter.ts +353 -0
- package/src/hub/useHubRefs.ts +53 -0
- package/src/hub/utils.ts +322 -0
- package/src/index.ts +1 -0
- package/src/legacy/autoConnect.ts +78 -0
- package/src/legacy/helpers.ts +17 -92
- package/src/legacy/mod.ts +13 -0
- package/src/legacy/types.ts +16 -6
- package/src/legacy/useAutoConnect.ts +8 -16
- package/src/legacy/useLegacyProviders.ts +23 -6
- package/src/legacy/utils.ts +7 -0
- package/src/provider.tsx +3 -3
- package/src/test-utils/env.ts +10 -0
- package/src/test-utils/fixtures.ts +238 -0
- package/src/useProviders.ts +120 -0
- package/dist/legacy/constants.d.ts +0 -2
- package/dist/legacy/constants.d.ts.map +0 -1
- package/src/legacy/constants.ts +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
namsepace: 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
|
+
|
|
57
|
+
#listFromLegacy(): LastConnectedWalletsStorage {
|
|
58
|
+
const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
59
|
+
const lastConnectedWallets =
|
|
60
|
+
persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS) || [];
|
|
61
|
+
const output: LastConnectedWalletsStorage = {};
|
|
62
|
+
lastConnectedWallets.forEach((provider) => {
|
|
63
|
+
// Setting empty namespaces
|
|
64
|
+
output[provider] = [];
|
|
65
|
+
});
|
|
66
|
+
return output;
|
|
67
|
+
}
|
|
68
|
+
#listFromHub(): LastConnectedWalletsStorage {
|
|
69
|
+
const persistor = new Persistor<LastConnectedWalletsStorage>();
|
|
70
|
+
const lastConnectedWallets =
|
|
71
|
+
persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {};
|
|
72
|
+
return lastConnectedWallets;
|
|
73
|
+
}
|
|
74
|
+
#addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void {
|
|
75
|
+
const storage = new Persistor<LastConnectedWalletsStorage>();
|
|
76
|
+
const data = storage.getItem(this.#storageKey) || {};
|
|
77
|
+
|
|
78
|
+
storage.setItem(this.#storageKey, {
|
|
79
|
+
...data,
|
|
80
|
+
[providerId]: namespaces,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
#addWalletToLegacy(providerId: string): void {
|
|
84
|
+
const storage = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
85
|
+
const data = storage.getItem(this.#storageKey) || [];
|
|
86
|
+
|
|
87
|
+
storage.setItem(LEGACY_LAST_CONNECTED_WALLETS, data.concat(providerId));
|
|
88
|
+
}
|
|
89
|
+
#removeWalletsFromHub(providerIds?: string[]): void {
|
|
90
|
+
const persistor = new Persistor<LastConnectedWalletsStorage>();
|
|
91
|
+
const storageState = persistor.getItem(this.#storageKey) || {};
|
|
92
|
+
|
|
93
|
+
// Remove all wallets
|
|
94
|
+
if (!providerIds) {
|
|
95
|
+
persistor.setItem(this.#storageKey, {});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Remove some of the wallets
|
|
100
|
+
providerIds.forEach((providerId) => {
|
|
101
|
+
if (storageState[providerId]) {
|
|
102
|
+
delete storageState[providerId];
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
persistor.setItem(this.#storageKey, storageState);
|
|
107
|
+
}
|
|
108
|
+
#removeWalletsFromLegacy(providerIds?: string[]): void {
|
|
109
|
+
const persistor = new Persistor<LegacyLastConnectedWalletsStorage>();
|
|
110
|
+
const storageState = persistor.getItem(this.#storageKey) || [];
|
|
111
|
+
|
|
112
|
+
// Remove all wallets
|
|
113
|
+
if (!providerIds) {
|
|
114
|
+
persistor.setItem(this.#storageKey, []);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Remove some of the wallets
|
|
119
|
+
persistor.setItem(
|
|
120
|
+
LEGACY_LAST_CONNECTED_WALLETS,
|
|
121
|
+
storageState.filter((wallet) => !providerIds.includes(wallet))
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/hub/mod.ts
ADDED
package/src/hub/types.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CommonNamespaces,
|
|
3
|
+
FindProxiedNamespace,
|
|
4
|
+
ProviderInfo,
|
|
5
|
+
} from '@rango-dev/wallets-core';
|
|
6
|
+
|
|
7
|
+
export type AllProxiedNamespaces = FindProxiedNamespace<
|
|
8
|
+
keyof CommonNamespaces,
|
|
9
|
+
CommonNamespaces
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
export type ExtensionLink = keyof ProviderInfo['extensions'];
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import type { AllProxiedNamespaces, ExtensionLink } from './types.js';
|
|
2
|
+
import type { Providers } from '../index.js';
|
|
3
|
+
import type { Provider } from '@rango-dev/wallets-core';
|
|
4
|
+
import type { LegacyNamespaceInputForConnect } from '@rango-dev/wallets-core/legacy';
|
|
5
|
+
import type { VersionedProviders } from '@rango-dev/wallets-core/utils';
|
|
6
|
+
|
|
7
|
+
import { type WalletInfo } from '@rango-dev/wallets-shared';
|
|
8
|
+
import { useEffect, useRef, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
type ConnectResult,
|
|
12
|
+
HUB_LAST_CONNECTED_WALLETS,
|
|
13
|
+
type ProviderContext,
|
|
14
|
+
type ProviderProps,
|
|
15
|
+
} from '../legacy/mod.js';
|
|
16
|
+
import { useAutoConnect } from '../legacy/useAutoConnect.js';
|
|
17
|
+
|
|
18
|
+
import { autoConnect } from './autoConnect.js';
|
|
19
|
+
import { fromAccountIdToLegacyAddressFormat } from './helpers.js';
|
|
20
|
+
import {
|
|
21
|
+
LastConnectedWalletsFromStorage,
|
|
22
|
+
type NamespaceInput,
|
|
23
|
+
} from './lastConnectedWallets.js';
|
|
24
|
+
import { useHubRefs } from './useHubRefs.js';
|
|
25
|
+
import {
|
|
26
|
+
checkHubStateAndTriggerEvents,
|
|
27
|
+
getLegacyProvider,
|
|
28
|
+
transformHubResultToLegacyResult,
|
|
29
|
+
tryConvertNamespaceNetworkToChainInfo,
|
|
30
|
+
} from './utils.js';
|
|
31
|
+
|
|
32
|
+
export type UseAdapterParams = Omit<ProviderProps, 'providers'> & {
|
|
33
|
+
providers: Provider[];
|
|
34
|
+
/** This is only will be used to access some parts of the legacy provider that doesn't exists in Hub. */
|
|
35
|
+
allVersionedProviders: VersionedProviders[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function useHubAdapter(params: UseAdapterParams): ProviderContext {
|
|
39
|
+
const { getStore, getHub } = useHubRefs(params.providers);
|
|
40
|
+
const [, rerender] = useState(0);
|
|
41
|
+
// useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes.
|
|
42
|
+
const dataRef = useRef({
|
|
43
|
+
onUpdateState: params.onUpdateState,
|
|
44
|
+
allVersionedProviders: params.allVersionedProviders,
|
|
45
|
+
allBlockChains: params.allBlockChains,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
dataRef.current = {
|
|
50
|
+
onUpdateState: params.onUpdateState,
|
|
51
|
+
allVersionedProviders: params.allVersionedProviders,
|
|
52
|
+
allBlockChains: params.allBlockChains,
|
|
53
|
+
};
|
|
54
|
+
}, [params]);
|
|
55
|
+
|
|
56
|
+
// Initialize instances
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
const runOnInit = () => {
|
|
59
|
+
getHub().init();
|
|
60
|
+
|
|
61
|
+
rerender((currentRender) => currentRender + 1);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Then will call init whenever page is ready.
|
|
65
|
+
const initHubWhenPageIsReady = (event: Event) => {
|
|
66
|
+
// Then will call init whenever page is ready.
|
|
67
|
+
if (
|
|
68
|
+
event.target &&
|
|
69
|
+
(event.target as Document).readyState === 'complete'
|
|
70
|
+
) {
|
|
71
|
+
runOnInit();
|
|
72
|
+
document.removeEventListener(
|
|
73
|
+
'readystatechange',
|
|
74
|
+
initHubWhenPageIsReady
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Try to run, maybe it's ready.
|
|
80
|
+
runOnInit();
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* Try again when the page has been completely loaded.
|
|
84
|
+
* Some of wallets, take some time to be fully injected and loaded.
|
|
85
|
+
*/
|
|
86
|
+
document.addEventListener('readystatechange', initHubWhenPageIsReady);
|
|
87
|
+
|
|
88
|
+
getStore().subscribe((curr, prev) => {
|
|
89
|
+
if (dataRef.current.onUpdateState) {
|
|
90
|
+
checkHubStateAndTriggerEvents(
|
|
91
|
+
getHub(),
|
|
92
|
+
curr,
|
|
93
|
+
prev,
|
|
94
|
+
dataRef.current.onUpdateState,
|
|
95
|
+
dataRef.current.allVersionedProviders,
|
|
96
|
+
dataRef.current.allBlockChains
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
rerender((currentRender) => currentRender + 1);
|
|
100
|
+
});
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
103
|
+
useAutoConnect({
|
|
104
|
+
autoConnect: params.autoConnect,
|
|
105
|
+
allBlockChains: params.allBlockChains,
|
|
106
|
+
autoConnectHandler: () => {
|
|
107
|
+
void autoConnect({
|
|
108
|
+
getLegacyProvider: getLegacyProvider.bind(
|
|
109
|
+
null,
|
|
110
|
+
params.allVersionedProviders
|
|
111
|
+
),
|
|
112
|
+
allBlockChains: params.allBlockChains,
|
|
113
|
+
getHub,
|
|
114
|
+
wallets: params.configs?.wallets,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage(
|
|
120
|
+
HUB_LAST_CONNECTED_WALLETS
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const api: ProviderContext = {
|
|
124
|
+
canSwitchNetworkTo(type, network) {
|
|
125
|
+
const provider = getLegacyProvider(params.allVersionedProviders, type);
|
|
126
|
+
const switchTo = provider.canSwitchNetworkTo;
|
|
127
|
+
|
|
128
|
+
if (!switchTo) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return switchTo({
|
|
133
|
+
network,
|
|
134
|
+
meta: params.allBlockChains || [],
|
|
135
|
+
provider: provider.getInstance(),
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
async connect(type, namespaces) {
|
|
139
|
+
const wallet = getHub().get(type);
|
|
140
|
+
if (!wallet) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`You should add ${type} to provider first then call 'connect'.`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!namespaces) {
|
|
147
|
+
throw new Error('Passing namespace to `connect` is required.');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Check `namespace` and look into hub to see how it can match given namespace to hub namespace.
|
|
151
|
+
const targetNamespaces: [
|
|
152
|
+
LegacyNamespaceInputForConnect,
|
|
153
|
+
AllProxiedNamespaces
|
|
154
|
+
][] = [];
|
|
155
|
+
namespaces.forEach((namespace) => {
|
|
156
|
+
const targetNamespace = namespace.namespace;
|
|
157
|
+
|
|
158
|
+
const result = wallet.findByNamespace(targetNamespace);
|
|
159
|
+
|
|
160
|
+
if (!result) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
targetNamespaces.push([namespace, result]);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Keeping only namespaces that connected successfully, then we'll store them on storage for auto connect functionality.
|
|
170
|
+
const successfulyConnectedNamespaces: NamespaceInput[] = [];
|
|
171
|
+
|
|
172
|
+
// Try to run `connect` on matched namespaces
|
|
173
|
+
const connectResultFromTargetNamespaces = targetNamespaces.map(
|
|
174
|
+
async ([namespaceInput, namespace]) => {
|
|
175
|
+
const network = tryConvertNamespaceNetworkToChainInfo(
|
|
176
|
+
namespaceInput,
|
|
177
|
+
params.allBlockChains || []
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
/*
|
|
181
|
+
* `connect` can have different interfaces (e.g. Solana -> .connect(), EVM -> .connect("0x1") ),
|
|
182
|
+
* our assumption here is all the `connect` hasn't chain or if they have, they will accept it in first argument.
|
|
183
|
+
* By this assumption, always passing a chain should be problematic since it will be ignored if the namespace's `connect` hasn't chain.
|
|
184
|
+
*/
|
|
185
|
+
const result = namespace.connect(network);
|
|
186
|
+
return result
|
|
187
|
+
.then<ConnectResult>(transformHubResultToLegacyResult)
|
|
188
|
+
.then((res) => {
|
|
189
|
+
successfulyConnectedNamespaces.push({
|
|
190
|
+
namsepace: namespaceInput.namespace,
|
|
191
|
+
network: namespaceInput.network,
|
|
192
|
+
});
|
|
193
|
+
return res;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// If Provider has support for auto connect, we will add the wallet to storage.
|
|
199
|
+
const legacyProvider = getLegacyProvider(
|
|
200
|
+
params.allVersionedProviders,
|
|
201
|
+
type
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
if (legacyProvider.canEagerConnect) {
|
|
205
|
+
void Promise.allSettled(connectResultFromTargetNamespaces).then(() => {
|
|
206
|
+
if (successfulyConnectedNamespaces.length > 0) {
|
|
207
|
+
lastConnectedWalletsFromStorage.addWallet(
|
|
208
|
+
type,
|
|
209
|
+
successfulyConnectedNamespaces
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const connectResultWithLegacyFormat = await Promise.all(
|
|
216
|
+
connectResultFromTargetNamespaces
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
return connectResultWithLegacyFormat;
|
|
220
|
+
},
|
|
221
|
+
async disconnect(type) {
|
|
222
|
+
const wallet = getHub().get(type);
|
|
223
|
+
if (!wallet) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`You should add ${type} to provider first then call 'connect'.`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
wallet.getAll().forEach((namespace) => {
|
|
230
|
+
return namespace.disconnect();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (params.autoConnect) {
|
|
234
|
+
lastConnectedWalletsFromStorage.removeWallets([type]);
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
disconnectAll() {
|
|
238
|
+
throw new Error('`disconnectAll` not implemented');
|
|
239
|
+
},
|
|
240
|
+
async getSigners(type) {
|
|
241
|
+
const provider = getLegacyProvider(params.allVersionedProviders, type);
|
|
242
|
+
return provider.getSigners(provider.getInstance());
|
|
243
|
+
},
|
|
244
|
+
getWalletInfo(type) {
|
|
245
|
+
const wallet = getHub().get(type);
|
|
246
|
+
if (!wallet) {
|
|
247
|
+
throw new Error(`You should add ${type} to provider first.`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const info = wallet.info();
|
|
251
|
+
if (!info) {
|
|
252
|
+
throw new Error('Your provider should have required `info`.');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const provider = getLegacyProvider(params.allVersionedProviders, type);
|
|
256
|
+
|
|
257
|
+
const installLink: Exclude<WalletInfo['installLink'], string> = {
|
|
258
|
+
DEFAULT: '',
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage`
|
|
262
|
+
Object.keys(info.extensions).forEach((k) => {
|
|
263
|
+
const key = k as ExtensionLink;
|
|
264
|
+
|
|
265
|
+
if (info.extensions[key] === 'homepage') {
|
|
266
|
+
installLink.DEFAULT = info.extensions[key] || '';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const allowedKeys: ExtensionLink[] = [
|
|
270
|
+
'firefox',
|
|
271
|
+
'chrome',
|
|
272
|
+
'brave',
|
|
273
|
+
'edge',
|
|
274
|
+
];
|
|
275
|
+
if (allowedKeys.includes(key)) {
|
|
276
|
+
const upperCasedKey = key.toUpperCase() as keyof Exclude<
|
|
277
|
+
WalletInfo['installLink'],
|
|
278
|
+
string
|
|
279
|
+
>;
|
|
280
|
+
installLink[upperCasedKey] = info.extensions[key] || '';
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const walletInfoFromLegacy = provider.getWalletInfo(
|
|
285
|
+
params.allBlockChains || []
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
name: info.name,
|
|
290
|
+
img: info.icon,
|
|
291
|
+
installLink: installLink,
|
|
292
|
+
// We don't have this values anymore, fill them with some values that communicate this.
|
|
293
|
+
color: 'red',
|
|
294
|
+
supportedChains: walletInfoFromLegacy.supportedChains,
|
|
295
|
+
isContractWallet: false,
|
|
296
|
+
mobileWallet: false,
|
|
297
|
+
// if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate.
|
|
298
|
+
showOnMobile: undefined,
|
|
299
|
+
needsNamespace: walletInfoFromLegacy.needsNamespace,
|
|
300
|
+
needsDerivationPath: walletInfoFromLegacy.needsDerivationPath,
|
|
301
|
+
|
|
302
|
+
isHub: true,
|
|
303
|
+
properties: wallet.info()?.properties,
|
|
304
|
+
};
|
|
305
|
+
},
|
|
306
|
+
providers() {
|
|
307
|
+
const output: Providers = {};
|
|
308
|
+
|
|
309
|
+
Array.from(getHub().getAll().keys()).forEach((id) => {
|
|
310
|
+
try {
|
|
311
|
+
const provider = getLegacyProvider(params.allVersionedProviders, id);
|
|
312
|
+
output[id] = provider.getInstance();
|
|
313
|
+
} catch (e) {
|
|
314
|
+
console.warn(e);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return output;
|
|
319
|
+
},
|
|
320
|
+
state(type) {
|
|
321
|
+
const result = getHub().state();
|
|
322
|
+
const provider = result[type];
|
|
323
|
+
|
|
324
|
+
if (!provider) {
|
|
325
|
+
throw new Error(
|
|
326
|
+
`It seems your requested provider doesn't exist in hub. Provider Id: ${type}`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const accounts = provider.namespaces
|
|
331
|
+
.filter((namespace) => namespace.connected)
|
|
332
|
+
.flatMap((namespace) =>
|
|
333
|
+
namespace.accounts?.map(fromAccountIdToLegacyAddressFormat)
|
|
334
|
+
)
|
|
335
|
+
.filter((account): account is string => !!account);
|
|
336
|
+
|
|
337
|
+
const coreState = {
|
|
338
|
+
connected: provider.connected,
|
|
339
|
+
connecting: provider.connecting,
|
|
340
|
+
installed: provider.installed,
|
|
341
|
+
reachable: true,
|
|
342
|
+
accounts: accounts,
|
|
343
|
+
network: null,
|
|
344
|
+
};
|
|
345
|
+
return coreState;
|
|
346
|
+
},
|
|
347
|
+
suggestAndConnect(_type, _network): never {
|
|
348
|
+
throw new Error('`suggestAndConnect` is not implemented');
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
return api;
|
|
353
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Provider, Store } from '@rango-dev/wallets-core';
|
|
2
|
+
|
|
3
|
+
import { createStore, Hub } from '@rango-dev/wallets-core';
|
|
4
|
+
import { useRef } from 'react';
|
|
5
|
+
|
|
6
|
+
import { checkProviderListsEquality } from './utils.js';
|
|
7
|
+
|
|
8
|
+
export function useHubRefs(providers: Provider[]) {
|
|
9
|
+
const store = useRef<Store | null>(null);
|
|
10
|
+
|
|
11
|
+
const hub = useRef<Hub | null>(null);
|
|
12
|
+
|
|
13
|
+
function createHub() {
|
|
14
|
+
const createdHub = new Hub({
|
|
15
|
+
store: getStore(),
|
|
16
|
+
});
|
|
17
|
+
/*
|
|
18
|
+
* First add providers to hub
|
|
19
|
+
* This helps to `getWalletInfo` be usable, before initialize.
|
|
20
|
+
*/
|
|
21
|
+
providers.forEach((provider) => {
|
|
22
|
+
createdHub.add(provider.id, provider);
|
|
23
|
+
});
|
|
24
|
+
hub.current = createdHub;
|
|
25
|
+
return createdHub;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents
|
|
29
|
+
function getStore() {
|
|
30
|
+
if (store.current !== null) {
|
|
31
|
+
return store.current;
|
|
32
|
+
}
|
|
33
|
+
const createdStore = createStore();
|
|
34
|
+
store.current = createdStore;
|
|
35
|
+
return createdStore;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getHub(): Hub {
|
|
39
|
+
const hubProviders = hub.current?.getAll();
|
|
40
|
+
|
|
41
|
+
if (
|
|
42
|
+
!hub.current ||
|
|
43
|
+
!hubProviders ||
|
|
44
|
+
// If hub does not contain a provider, it should be added
|
|
45
|
+
!checkProviderListsEquality(Array.from(hubProviders.values()), providers)
|
|
46
|
+
) {
|
|
47
|
+
return createHub();
|
|
48
|
+
}
|
|
49
|
+
return hub.current;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { getStore, getHub };
|
|
53
|
+
}
|