@openzeppelin/ui-react 1.2.0 → 2.0.1
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/README.md +53 -58
- package/dist/index.cjs +281 -189
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -50
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +61 -50
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +279 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -32,111 +32,159 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
32
32
|
let _openzeppelin_ui_components = require("@openzeppelin/ui-components");
|
|
33
33
|
|
|
34
34
|
//#region src/version.ts
|
|
35
|
-
const VERSION = "
|
|
35
|
+
const VERSION = "2.0.1";
|
|
36
36
|
|
|
37
37
|
//#endregion
|
|
38
38
|
//#region src/hooks/AdapterContext.tsx
|
|
39
39
|
/**
|
|
40
40
|
* AdapterContext.tsx
|
|
41
41
|
*
|
|
42
|
-
* This file defines the React Context used for the
|
|
42
|
+
* This file defines the React Context used for the runtime singleton pattern.
|
|
43
43
|
* It provides types and the context definition, but the actual implementation
|
|
44
|
-
* is in the
|
|
44
|
+
* is in the `RuntimeProvider` component.
|
|
45
45
|
*
|
|
46
|
-
* The
|
|
46
|
+
* The runtime singleton pattern ensures that only one runtime instance exists
|
|
47
47
|
* per network configuration, which is critical for consistent wallet connection
|
|
48
48
|
* state across the application.
|
|
49
49
|
*/
|
|
50
50
|
/**
|
|
51
|
-
* The React Context that provides
|
|
52
|
-
* Components can access this through the
|
|
51
|
+
* The React Context that provides runtime registry access throughout the app.
|
|
52
|
+
* Components can access this through the `useRuntimeContext` hook.
|
|
53
53
|
*/
|
|
54
|
-
const
|
|
54
|
+
const RuntimeContext = (0, react.createContext)(null);
|
|
55
55
|
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region src/hooks/AdapterProvider.tsx
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* RuntimeProvider.tsx
|
|
60
60
|
*
|
|
61
|
-
* This file implements the
|
|
62
|
-
*
|
|
63
|
-
* that only one
|
|
61
|
+
* This file implements the Runtime Provider component which manages a registry of
|
|
62
|
+
* runtime instances. It's a key part of the runtime singleton pattern which ensures
|
|
63
|
+
* that only one runtime instance exists per network configuration.
|
|
64
64
|
*
|
|
65
|
-
* The
|
|
66
|
-
* components to access the same
|
|
65
|
+
* The runtime registry is shared across the application via React Context, allowing
|
|
66
|
+
* components to access the same runtime instances and maintain consistent wallet
|
|
67
67
|
* connection state.
|
|
68
68
|
*
|
|
69
69
|
* IMPORTANT: This implementation needs special care to avoid React state update errors
|
|
70
70
|
* during component rendering. Direct state updates during render are not allowed, which
|
|
71
|
-
* is why
|
|
71
|
+
* is why runtime loading is controlled carefully.
|
|
72
72
|
*/
|
|
73
73
|
/**
|
|
74
|
-
* Provider component that manages
|
|
75
|
-
* to avoid creating multiple instances of the same
|
|
74
|
+
* Provider component that manages runtime instances centrally
|
|
75
|
+
* to avoid creating multiple instances of the same runtime.
|
|
76
76
|
*
|
|
77
77
|
* This component:
|
|
78
|
-
* 1. Maintains a registry of
|
|
79
|
-
* 2. Tracks loading states for
|
|
80
|
-
* 3. Provides a function to get or load
|
|
81
|
-
* 4. Ensures
|
|
78
|
+
* 1. Maintains a registry of runtime instances by network ID
|
|
79
|
+
* 2. Tracks loading states for runtimes being initialized
|
|
80
|
+
* 3. Provides a function to get or load runtimes for specific networks
|
|
81
|
+
* 4. Ensures runtime instances are reused when possible
|
|
82
82
|
*/
|
|
83
|
-
function
|
|
84
|
-
const [
|
|
83
|
+
function RuntimeProvider({ children, resolveRuntime }) {
|
|
84
|
+
const [runtimeRegistry, setRuntimeRegistry] = (0, react.useState)({});
|
|
85
85
|
const [loadingNetworks, setLoadingNetworks] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
86
|
+
const runtimeRegistryRef = (0, react.useRef)(runtimeRegistry);
|
|
87
|
+
const failedNetworksRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
86
88
|
(0, react.useEffect)(() => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
runtimeRegistryRef.current = runtimeRegistry;
|
|
90
|
+
}, [runtimeRegistry]);
|
|
91
|
+
(0, react.useEffect)(() => {
|
|
92
|
+
failedNetworksRef.current = /* @__PURE__ */ new Set();
|
|
93
|
+
}, [resolveRuntime]);
|
|
94
|
+
(0, react.useEffect)(() => {
|
|
95
|
+
return () => {
|
|
96
|
+
Object.values(runtimeRegistryRef.current).forEach((runtime) => {
|
|
97
|
+
runtime.dispose();
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
}, []);
|
|
101
|
+
(0, react.useEffect)(() => {
|
|
102
|
+
const runtimeCount = Object.keys(runtimeRegistry).length;
|
|
103
|
+
if (runtimeCount > 0) _openzeppelin_ui_utils.logger.info("RuntimeProvider", `Registry contains ${runtimeCount} runtimes:`, {
|
|
104
|
+
networkIds: Object.keys(runtimeRegistry),
|
|
90
105
|
loadingCount: loadingNetworks.size,
|
|
91
106
|
loadingNetworkIds: Array.from(loadingNetworks)
|
|
92
107
|
});
|
|
93
|
-
}, [
|
|
108
|
+
}, [runtimeRegistry, loadingNetworks]);
|
|
109
|
+
/**
|
|
110
|
+
* Evicts a runtime from the registry by network ID and disposes it.
|
|
111
|
+
* This is the safe counterpart to `getRuntimeForNetwork`: callers should only
|
|
112
|
+
* release a runtime after they have already promoted its replacement.
|
|
113
|
+
*
|
|
114
|
+
* Disposal is deferred to the next macrotask so React's commit phase
|
|
115
|
+
* (including development-mode prop diffing) can finish reading the old
|
|
116
|
+
* runtime's properties without hitting the RuntimeDisposedError proxy trap.
|
|
117
|
+
*/
|
|
118
|
+
const releaseRuntime = (0, react.useCallback)((networkId) => {
|
|
119
|
+
const runtime = runtimeRegistryRef.current[networkId];
|
|
120
|
+
if (!runtime) return;
|
|
121
|
+
_openzeppelin_ui_utils.logger.info("RuntimeProvider", `Releasing runtime for network ${networkId}`);
|
|
122
|
+
setRuntimeRegistry((prev) => {
|
|
123
|
+
const next = { ...prev };
|
|
124
|
+
delete next[networkId];
|
|
125
|
+
return next;
|
|
126
|
+
});
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
try {
|
|
129
|
+
runtime.dispose();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
_openzeppelin_ui_utils.logger.error("RuntimeProvider", `Error disposing runtime for network ${networkId}:`, error);
|
|
132
|
+
}
|
|
133
|
+
}, 0);
|
|
134
|
+
}, []);
|
|
94
135
|
/**
|
|
95
|
-
* Function to get or create
|
|
136
|
+
* Function to get or create a runtime for a network
|
|
96
137
|
*
|
|
97
|
-
* IMPORTANT:
|
|
98
|
-
*
|
|
138
|
+
* IMPORTANT: Runtime loading is coordinated carefully to avoid React state updates
|
|
139
|
+
* during render, which would cause errors.
|
|
99
140
|
*
|
|
100
141
|
* This function:
|
|
101
|
-
* 1. Returns existing
|
|
102
|
-
* 2. Reports loading state for
|
|
103
|
-
* 3. Initiates
|
|
142
|
+
* 1. Returns existing runtimes immediately if available
|
|
143
|
+
* 2. Reports loading state for runtimes being initialized
|
|
144
|
+
* 3. Initiates runtime loading when needed
|
|
104
145
|
*/
|
|
105
|
-
const
|
|
146
|
+
const getRuntimeForNetwork = (0, react.useCallback)((networkConfig) => {
|
|
106
147
|
if (!networkConfig) return {
|
|
107
|
-
|
|
148
|
+
runtime: null,
|
|
108
149
|
isLoading: false
|
|
109
150
|
};
|
|
110
151
|
const networkId = networkConfig.id;
|
|
111
|
-
_openzeppelin_ui_utils.logger.debug("
|
|
112
|
-
if (
|
|
113
|
-
_openzeppelin_ui_utils.logger.debug("
|
|
152
|
+
_openzeppelin_ui_utils.logger.debug("RuntimeProvider", `Runtime requested for network ${networkId}`);
|
|
153
|
+
if (runtimeRegistry[networkId]) {
|
|
154
|
+
_openzeppelin_ui_utils.logger.debug("RuntimeProvider", `Using existing runtime for network ${networkId}`);
|
|
114
155
|
return {
|
|
115
|
-
|
|
156
|
+
runtime: runtimeRegistry[networkId],
|
|
116
157
|
isLoading: false
|
|
117
158
|
};
|
|
118
159
|
}
|
|
119
160
|
if (loadingNetworks.has(networkId)) {
|
|
120
|
-
_openzeppelin_ui_utils.logger.debug("
|
|
161
|
+
_openzeppelin_ui_utils.logger.debug("RuntimeProvider", `Runtime for network ${networkId} is currently loading`);
|
|
121
162
|
return {
|
|
122
|
-
|
|
163
|
+
runtime: null,
|
|
123
164
|
isLoading: true
|
|
124
165
|
};
|
|
125
166
|
}
|
|
167
|
+
if (failedNetworksRef.current.has(networkId)) {
|
|
168
|
+
_openzeppelin_ui_utils.logger.debug("RuntimeProvider", `Runtime for network ${networkId} previously failed; skipping retry`);
|
|
169
|
+
return {
|
|
170
|
+
runtime: null,
|
|
171
|
+
isLoading: false
|
|
172
|
+
};
|
|
173
|
+
}
|
|
126
174
|
setLoadingNetworks((prev) => {
|
|
127
175
|
const newSet = new Set(prev);
|
|
128
176
|
newSet.add(networkId);
|
|
129
177
|
return newSet;
|
|
130
178
|
});
|
|
131
|
-
_openzeppelin_ui_utils.logger.info("
|
|
132
|
-
|
|
133
|
-
_openzeppelin_ui_utils.logger.info("
|
|
134
|
-
type:
|
|
135
|
-
objectId: Object.prototype.toString.call(
|
|
179
|
+
_openzeppelin_ui_utils.logger.info("RuntimeProvider", `Starting runtime initialization for network ${networkId} (${networkConfig.name})`);
|
|
180
|
+
resolveRuntime(networkConfig).then((runtime) => {
|
|
181
|
+
_openzeppelin_ui_utils.logger.info("RuntimeProvider", `Runtime for network ${networkId} loaded successfully`, {
|
|
182
|
+
type: runtime.constructor.name,
|
|
183
|
+
objectId: Object.prototype.toString.call(runtime)
|
|
136
184
|
});
|
|
137
|
-
|
|
185
|
+
setRuntimeRegistry((prev) => ({
|
|
138
186
|
...prev,
|
|
139
|
-
[networkId]:
|
|
187
|
+
[networkId]: runtime
|
|
140
188
|
}));
|
|
141
189
|
setLoadingNetworks((prev) => {
|
|
142
190
|
const newSet = new Set(prev);
|
|
@@ -144,7 +192,8 @@ function AdapterProvider({ children, resolveAdapter }) {
|
|
|
144
192
|
return newSet;
|
|
145
193
|
});
|
|
146
194
|
}).catch((error) => {
|
|
147
|
-
_openzeppelin_ui_utils.logger.error("
|
|
195
|
+
_openzeppelin_ui_utils.logger.error("RuntimeProvider", `Error loading runtime for network ${networkId}:`, error);
|
|
196
|
+
failedNetworksRef.current.add(networkId);
|
|
148
197
|
setLoadingNetworks((prev) => {
|
|
149
198
|
const newSet = new Set(prev);
|
|
150
199
|
newSet.delete(networkId);
|
|
@@ -152,16 +201,19 @@ function AdapterProvider({ children, resolveAdapter }) {
|
|
|
152
201
|
});
|
|
153
202
|
});
|
|
154
203
|
return {
|
|
155
|
-
|
|
204
|
+
runtime: null,
|
|
156
205
|
isLoading: true
|
|
157
206
|
};
|
|
158
207
|
}, [
|
|
159
|
-
|
|
208
|
+
runtimeRegistry,
|
|
160
209
|
loadingNetworks,
|
|
161
|
-
|
|
210
|
+
resolveRuntime
|
|
162
211
|
]);
|
|
163
|
-
const contextValue = (0, react.useMemo)(() => ({
|
|
164
|
-
|
|
212
|
+
const contextValue = (0, react.useMemo)(() => ({
|
|
213
|
+
getRuntimeForNetwork,
|
|
214
|
+
releaseRuntime
|
|
215
|
+
}), [getRuntimeForNetwork, releaseRuntime]);
|
|
216
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeContext.Provider, {
|
|
165
217
|
value: contextValue,
|
|
166
218
|
children
|
|
167
219
|
});
|
|
@@ -179,7 +231,7 @@ function AdapterProvider({ children, resolveAdapter }) {
|
|
|
179
231
|
* consuming package's bundle. This creates MULTIPLE instances of this module:
|
|
180
232
|
*
|
|
181
233
|
* 1. The app's direct import → packages/react/dist/index.js
|
|
182
|
-
* 2. The adapter's inlined copy → .vite/deps/@
|
|
234
|
+
* 2. The adapter package's inlined copy → .vite/deps/@openzeppelin_adapter_evm.js
|
|
183
235
|
*
|
|
184
236
|
* Since React contexts use referential identity, these two module instances have
|
|
185
237
|
* DIFFERENT context objects. When the adapter's components call useWalletState(),
|
|
@@ -241,54 +293,88 @@ function useWalletState() {
|
|
|
241
293
|
/**
|
|
242
294
|
* useAdapterContext.ts
|
|
243
295
|
*
|
|
244
|
-
* This file provides a hook to access the
|
|
245
|
-
* It's a critical part of the
|
|
246
|
-
* access the centralized
|
|
296
|
+
* This file provides a hook to access the runtime context throughout the application.
|
|
297
|
+
* It's a critical part of the runtime singleton pattern, allowing components to
|
|
298
|
+
* access the centralized runtime registry.
|
|
247
299
|
*
|
|
248
|
-
* The
|
|
249
|
-
* - Only one
|
|
300
|
+
* The runtime singleton pattern ensures:
|
|
301
|
+
* - Only one runtime instance exists per network
|
|
250
302
|
* - Wallet connection state is consistent across the app
|
|
251
|
-
* - Better performance by eliminating redundant
|
|
303
|
+
* - Better performance by eliminating redundant runtime initialization
|
|
252
304
|
*/
|
|
253
305
|
/**
|
|
254
|
-
* Hook to access the
|
|
306
|
+
* Hook to access the runtime context
|
|
255
307
|
*
|
|
256
|
-
* This hook provides access to the
|
|
257
|
-
* retrieves or creates
|
|
308
|
+
* This hook provides access to the `getRuntimeForNetwork` function which
|
|
309
|
+
* retrieves or creates runtime instances from the singleton registry.
|
|
258
310
|
*
|
|
259
|
-
* Components should typically use
|
|
311
|
+
* Components should typically use the higher-level wallet/runtime hooks instead
|
|
260
312
|
* of this hook directly, as it handles React state update timing properly.
|
|
261
313
|
*
|
|
262
|
-
* @throws Error if used outside of
|
|
263
|
-
* @returns The
|
|
314
|
+
* @throws Error if used outside of a RuntimeProvider context
|
|
315
|
+
* @returns The runtime context value
|
|
264
316
|
*/
|
|
265
|
-
function
|
|
266
|
-
const context = (0, react.useContext)(
|
|
267
|
-
if (!context) throw new Error("
|
|
317
|
+
function useRuntimeContext() {
|
|
318
|
+
const context = (0, react.useContext)(RuntimeContext);
|
|
319
|
+
if (!context) throw new Error("useRuntimeContext must be used within a RuntimeProvider");
|
|
268
320
|
return context;
|
|
269
321
|
}
|
|
270
322
|
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/hooks/walletSessionRegistry.ts
|
|
325
|
+
/**
|
|
326
|
+
* Returns the cached wallet session for an ecosystem, if present.
|
|
327
|
+
*
|
|
328
|
+
* @param registry - Current internal wallet session registry.
|
|
329
|
+
* @param ecosystem - Ecosystem key to resolve.
|
|
330
|
+
* @returns The cached session entry or `null` when the ecosystem has not been configured yet.
|
|
331
|
+
*/
|
|
332
|
+
function getWalletSession(registry, ecosystem) {
|
|
333
|
+
if (!ecosystem) return null;
|
|
334
|
+
return registry[ecosystem] ?? null;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Inserts or replaces the cached wallet session for a single ecosystem.
|
|
338
|
+
*
|
|
339
|
+
* @param registry - Current internal wallet session registry.
|
|
340
|
+
* @param session - Session entry to cache.
|
|
341
|
+
* @returns A new registry object containing the upserted ecosystem session.
|
|
342
|
+
*/
|
|
343
|
+
function upsertWalletSession(registry, session) {
|
|
344
|
+
return {
|
|
345
|
+
...registry,
|
|
346
|
+
[session.ecosystem]: session
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
271
350
|
//#endregion
|
|
272
351
|
//#region src/hooks/WalletStateProvider.tsx
|
|
273
352
|
/**
|
|
274
|
-
* Configures the
|
|
353
|
+
* Configures the runtime's UI kit capability and returns the ecosystem session artifacts.
|
|
275
354
|
*/
|
|
276
|
-
async function
|
|
355
|
+
async function configureRuntimeUiKit(runtime, loadConfigModule, programmaticOverrides = {}) {
|
|
356
|
+
const uiKit = runtime.uiKit;
|
|
357
|
+
if (!uiKit) return {
|
|
358
|
+
providerComponent: null,
|
|
359
|
+
hooks: null
|
|
360
|
+
};
|
|
277
361
|
try {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
_openzeppelin_ui_utils.logger.info("[WSP
|
|
362
|
+
const hasUiKitOverride = Object.keys(programmaticOverrides).length > 0;
|
|
363
|
+
if (typeof uiKit.configureUiKit === "function") {
|
|
364
|
+
const nextUiKitConfig = { ...programmaticOverrides };
|
|
365
|
+
_openzeppelin_ui_utils.logger.info("[WSP configureRuntimeUiKit]", hasUiKitOverride ? `Applying explicit UI kit overrides for runtime: ${runtime.networkConfig.id}` : `Initializing runtime UI kit from adapter/app defaults for runtime: ${runtime.networkConfig.id}`);
|
|
366
|
+
await uiKit.configureUiKit(nextUiKitConfig, { loadUiKitNativeConfig: loadConfigModule });
|
|
367
|
+
_openzeppelin_ui_utils.logger.info("[WSP configureRuntimeUiKit] configureUiKit completed for runtime:", runtime.networkConfig.id);
|
|
282
368
|
}
|
|
283
|
-
const providerComponent =
|
|
284
|
-
const hooks =
|
|
285
|
-
_openzeppelin_ui_utils.logger.info("[WSP
|
|
369
|
+
const providerComponent = uiKit.getEcosystemReactUiContextProvider?.() || null;
|
|
370
|
+
const hooks = uiKit.getEcosystemReactHooks?.() || null;
|
|
371
|
+
_openzeppelin_ui_utils.logger.info("[WSP configureRuntimeUiKit]", "UI provider and hooks retrieved successfully.");
|
|
286
372
|
return {
|
|
287
373
|
providerComponent,
|
|
288
374
|
hooks
|
|
289
375
|
};
|
|
290
376
|
} catch (error) {
|
|
291
|
-
_openzeppelin_ui_utils.logger.error("[WSP
|
|
377
|
+
_openzeppelin_ui_utils.logger.error("[WSP configureRuntimeUiKit]", "Error during runtime UI setup:", error);
|
|
292
378
|
throw error;
|
|
293
379
|
}
|
|
294
380
|
}
|
|
@@ -298,26 +384,28 @@ async function configureAdapterUiKit(adapter, loadConfigModule, programmaticOver
|
|
|
298
384
|
* It is responsible for:
|
|
299
385
|
* 1. Managing the globally selected active network ID (`activeNetworkId`).
|
|
300
386
|
* 2. Deriving the full `NetworkConfig` object (`activeNetworkConfig`) for the active network.
|
|
301
|
-
* 3. Fetching and providing the corresponding `
|
|
302
|
-
* leveraging the `
|
|
303
|
-
* 4.
|
|
304
|
-
*
|
|
305
|
-
*
|
|
387
|
+
* 3. Fetching and providing the corresponding `EcosystemRuntime` (`activeRuntime`) for the active network,
|
|
388
|
+
* leveraging the `RuntimeProvider` to ensure runtime singletons.
|
|
389
|
+
* 4. Caching ecosystem-scoped wallet session artifacts (provider roots and facade hooks)
|
|
390
|
+
* independently from the network-scoped runtime.
|
|
391
|
+
* 5. Rendering the active ecosystem wallet provider (e.g., WagmiProvider for EVM) around its
|
|
392
|
+
* children, which is essential for the facade hooks to function correctly.
|
|
306
393
|
* 6. Providing a function (`setActiveNetworkId`) to change the globally active network.
|
|
307
394
|
*
|
|
308
395
|
* Consumers use the `useWalletState()` hook to access this global state.
|
|
309
|
-
* It should be placed high in the component tree, inside
|
|
396
|
+
* It should be placed high in the component tree, inside a `<RuntimeProvider>`.
|
|
310
397
|
*/
|
|
311
398
|
function WalletStateProvider({ children, initialNetworkId = null, getNetworkConfigById, loadConfigModule }) {
|
|
312
399
|
const [currentGlobalNetworkId, setCurrentGlobalNetworkIdState] = (0, react.useState)(initialNetworkId);
|
|
313
400
|
const [currentGlobalNetworkConfig, setCurrentGlobalNetworkConfig] = (0, react.useState)(null);
|
|
314
|
-
const [
|
|
315
|
-
const [
|
|
316
|
-
const [
|
|
317
|
-
const [
|
|
401
|
+
const [globalActiveRuntime, setGlobalActiveRuntime] = (0, react.useState)(null);
|
|
402
|
+
const [isGlobalRuntimeLoading, setIsGlobalRuntimeLoading] = (0, react.useState)(false);
|
|
403
|
+
const [walletSessionRegistry, setWalletSessionRegistry] = (0, react.useState)({});
|
|
404
|
+
const [activeWalletSessionEcosystem, setActiveWalletSessionEcosystem] = (0, react.useState)(null);
|
|
318
405
|
const [uiKitConfigVersion, setUiKitConfigVersion] = (0, react.useState)(0);
|
|
319
406
|
const [programmaticUiKitConfig, setProgrammaticUiKitConfig] = (0, react.useState)(void 0);
|
|
320
|
-
const {
|
|
407
|
+
const { getRuntimeForNetwork, releaseRuntime } = useRuntimeContext();
|
|
408
|
+
const promotedNetworkIdRef = (0, react.useRef)(null);
|
|
321
409
|
(0, react.useEffect)(() => {
|
|
322
410
|
const abortController = new AbortController();
|
|
323
411
|
async function fetchNetworkConfig() {
|
|
@@ -340,98 +428,115 @@ function WalletStateProvider({ children, initialNetworkId = null, getNetworkConf
|
|
|
340
428
|
}, [currentGlobalNetworkId, getNetworkConfigById]);
|
|
341
429
|
(0, react.useEffect)(() => {
|
|
342
430
|
const abortController = new AbortController();
|
|
343
|
-
async function
|
|
431
|
+
async function loadRuntimeAndConfigureUi() {
|
|
344
432
|
if (!currentGlobalNetworkConfig) {
|
|
345
433
|
if (!abortController.signal.aborted) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
434
|
+
const prevNetworkId = promotedNetworkIdRef.current;
|
|
435
|
+
setGlobalActiveRuntime(null);
|
|
436
|
+
setIsGlobalRuntimeLoading(false);
|
|
437
|
+
setActiveWalletSessionEcosystem(null);
|
|
438
|
+
if (prevNetworkId) {
|
|
439
|
+
releaseRuntime(prevNetworkId);
|
|
440
|
+
promotedNetworkIdRef.current = null;
|
|
441
|
+
}
|
|
350
442
|
}
|
|
351
443
|
return;
|
|
352
444
|
}
|
|
353
|
-
const {
|
|
445
|
+
const { runtime: newRuntime, isLoading: newIsLoading } = getRuntimeForNetwork(currentGlobalNetworkConfig);
|
|
354
446
|
if (abortController.signal.aborted) return;
|
|
355
|
-
|
|
356
|
-
if (
|
|
357
|
-
const { providerComponent, hooks } = await
|
|
447
|
+
setIsGlobalRuntimeLoading(newIsLoading);
|
|
448
|
+
if (newRuntime && !newIsLoading) try {
|
|
449
|
+
const { providerComponent, hooks } = await configureRuntimeUiKit(newRuntime, loadConfigModule, programmaticUiKitConfig);
|
|
358
450
|
if (!abortController.signal.aborted) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
451
|
+
const ecosystem = newRuntime.networkConfig.ecosystem;
|
|
452
|
+
const prevNetworkId = promotedNetworkIdRef.current;
|
|
453
|
+
const nextNetworkId = newRuntime.networkConfig.id;
|
|
454
|
+
setWalletSessionRegistry((prevRegistry) => upsertWalletSession(prevRegistry, {
|
|
455
|
+
ecosystem,
|
|
456
|
+
lastConfiguredNetworkId: nextNetworkId,
|
|
457
|
+
providerComponent,
|
|
458
|
+
hooks
|
|
459
|
+
}));
|
|
460
|
+
setGlobalActiveRuntime(newRuntime);
|
|
461
|
+
setActiveWalletSessionEcosystem(ecosystem);
|
|
462
|
+
promotedNetworkIdRef.current = nextNetworkId;
|
|
463
|
+
if (prevNetworkId && prevNetworkId !== nextNetworkId) releaseRuntime(prevNetworkId);
|
|
362
464
|
}
|
|
363
465
|
} catch (error) {
|
|
364
|
-
if (!abortController.signal.aborted)
|
|
365
|
-
_openzeppelin_ui_utils.logger.error("[WSP loadAdapterAndConfigureUi]", "Error during adapter UI setup:", error);
|
|
366
|
-
setAdapterUiContextProviderToRender(null);
|
|
367
|
-
setWalletFacadeHooks(null);
|
|
368
|
-
}
|
|
466
|
+
if (!abortController.signal.aborted) _openzeppelin_ui_utils.logger.error("[WSP loadRuntimeAndConfigureUi]", "Error during runtime UI setup:", error);
|
|
369
467
|
}
|
|
370
|
-
else if (!
|
|
468
|
+
else if (!newRuntime && !newIsLoading) {
|
|
371
469
|
if (!abortController.signal.aborted) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
470
|
+
const prevNetworkId = promotedNetworkIdRef.current;
|
|
471
|
+
setGlobalActiveRuntime(null);
|
|
472
|
+
setActiveWalletSessionEcosystem(null);
|
|
473
|
+
if (prevNetworkId) {
|
|
474
|
+
releaseRuntime(prevNetworkId);
|
|
475
|
+
promotedNetworkIdRef.current = null;
|
|
476
|
+
}
|
|
375
477
|
}
|
|
376
478
|
}
|
|
377
479
|
}
|
|
378
|
-
|
|
480
|
+
loadRuntimeAndConfigureUi();
|
|
379
481
|
return () => abortController.abort();
|
|
380
482
|
}, [
|
|
381
483
|
currentGlobalNetworkConfig,
|
|
382
|
-
|
|
484
|
+
getRuntimeForNetwork,
|
|
485
|
+
releaseRuntime,
|
|
383
486
|
loadConfigModule,
|
|
384
487
|
uiKitConfigVersion,
|
|
385
488
|
programmaticUiKitConfig
|
|
386
489
|
]);
|
|
387
490
|
/**
|
|
388
491
|
* Callback to set the globally active network ID.
|
|
389
|
-
* Also clears dependent states
|
|
492
|
+
* Also clears dependent states if the network ID is cleared.
|
|
390
493
|
*/
|
|
391
494
|
const setActiveNetworkIdCallback = (0, react.useCallback)((networkId) => {
|
|
392
495
|
_openzeppelin_ui_utils.logger.info("WalletStateProvider", `Setting global network ID to: ${networkId}`);
|
|
393
496
|
setCurrentGlobalNetworkIdState(networkId);
|
|
394
497
|
if (!networkId) {
|
|
395
498
|
setCurrentGlobalNetworkConfig(null);
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
499
|
+
setGlobalActiveRuntime(null);
|
|
500
|
+
setIsGlobalRuntimeLoading(false);
|
|
501
|
+
setActiveWalletSessionEcosystem(null);
|
|
399
502
|
}
|
|
400
503
|
}, []);
|
|
401
504
|
/**
|
|
402
|
-
* Callback to explicitly trigger a re-configuration of the active
|
|
505
|
+
* Callback to explicitly trigger a re-configuration of the active runtime's UI kit.
|
|
403
506
|
* This is useful when a UI kit setting changes (e.g., via a wizard) without a network change.
|
|
404
507
|
*/
|
|
405
|
-
const
|
|
508
|
+
const reconfigureActiveUiKit = (0, react.useCallback)((uiKitConfig) => {
|
|
406
509
|
_openzeppelin_ui_utils.logger.info("WalletStateProvider", "Explicitly triggering UI kit re-configuration by bumping version.", uiKitConfig);
|
|
407
510
|
setProgrammaticUiKitConfig(uiKitConfig);
|
|
408
511
|
setUiKitConfigVersion((v) => v + 1);
|
|
409
512
|
}, [setProgrammaticUiKitConfig, setUiKitConfigVersion]);
|
|
513
|
+
const activeWalletSession = (0, react.useMemo)(() => getWalletSession(walletSessionRegistry, activeWalletSessionEcosystem), [walletSessionRegistry, activeWalletSessionEcosystem]);
|
|
514
|
+
const walletFacadeHooks = activeWalletSession?.hooks ?? null;
|
|
410
515
|
const contextValue = (0, react.useMemo)(() => ({
|
|
411
516
|
activeNetworkId: currentGlobalNetworkId,
|
|
412
517
|
setActiveNetworkId: setActiveNetworkIdCallback,
|
|
413
518
|
activeNetworkConfig: currentGlobalNetworkConfig,
|
|
414
|
-
|
|
415
|
-
|
|
519
|
+
activeRuntime: globalActiveRuntime,
|
|
520
|
+
isRuntimeLoading: isGlobalRuntimeLoading,
|
|
416
521
|
walletFacadeHooks,
|
|
417
|
-
|
|
522
|
+
reconfigureActiveUiKit
|
|
418
523
|
}), [
|
|
419
524
|
currentGlobalNetworkId,
|
|
420
525
|
setActiveNetworkIdCallback,
|
|
421
526
|
currentGlobalNetworkConfig,
|
|
422
|
-
|
|
423
|
-
|
|
527
|
+
globalActiveRuntime,
|
|
528
|
+
isGlobalRuntimeLoading,
|
|
424
529
|
walletFacadeHooks,
|
|
425
|
-
|
|
530
|
+
reconfigureActiveUiKit
|
|
426
531
|
]);
|
|
427
|
-
const ActualProviderToRender =
|
|
532
|
+
const ActualProviderToRender = activeWalletSession?.providerComponent ?? null;
|
|
428
533
|
let childrenToRender;
|
|
429
534
|
if (ActualProviderToRender) {
|
|
430
|
-
const key =
|
|
431
|
-
_openzeppelin_ui_utils.logger.
|
|
535
|
+
const key = activeWalletSessionEcosystem || "unknown";
|
|
536
|
+
_openzeppelin_ui_utils.logger.debug("[WSP RENDER]", "Rendering runtime-provided UI context provider:", ActualProviderToRender.displayName || ActualProviderToRender.name || "UnknownComponent", "with key:", key);
|
|
432
537
|
childrenToRender = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActualProviderToRender, { children }, key);
|
|
433
538
|
} else {
|
|
434
|
-
_openzeppelin_ui_utils.logger.
|
|
539
|
+
_openzeppelin_ui_utils.logger.debug("[WSP RENDER]", "No runtime UI context provider to render. Rendering direct children.");
|
|
435
540
|
childrenToRender = children;
|
|
436
541
|
}
|
|
437
542
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WalletStateContext.Provider, {
|
|
@@ -575,14 +680,14 @@ const useAnalytics = () => {
|
|
|
575
680
|
//#endregion
|
|
576
681
|
//#region src/hooks/useWalletComponents.ts
|
|
577
682
|
/**
|
|
578
|
-
* Hook that provides direct access to wallet UI components from the active
|
|
683
|
+
* Hook that provides direct access to wallet UI components from the active runtime.
|
|
579
684
|
*
|
|
580
685
|
* Use this hook when you need full control over the layout and composition of
|
|
581
686
|
* wallet components. For standard layouts, prefer using `WalletConnectionUI`
|
|
582
687
|
* with its props forwarding capabilities.
|
|
583
688
|
*
|
|
584
|
-
* @returns The wallet components object, or null if no
|
|
585
|
-
* the
|
|
689
|
+
* @returns The wallet components object, or null if no runtime is active or
|
|
690
|
+
* the runtime doesn't provide wallet components.
|
|
586
691
|
*
|
|
587
692
|
* @example
|
|
588
693
|
* ```tsx
|
|
@@ -617,10 +722,11 @@ const useAnalytics = () => {
|
|
|
617
722
|
* ```
|
|
618
723
|
*/
|
|
619
724
|
function useWalletComponents() {
|
|
620
|
-
const {
|
|
621
|
-
|
|
725
|
+
const { activeNetworkConfig, activeRuntime, isRuntimeLoading } = useWalletState();
|
|
726
|
+
const activeUiKit = activeRuntime?.uiKit;
|
|
727
|
+
if (!!(isRuntimeLoading && activeRuntime?.networkConfig?.ecosystem && activeNetworkConfig?.ecosystem && activeRuntime.networkConfig.ecosystem !== activeNetworkConfig.ecosystem) || !activeUiKit || typeof activeUiKit.getEcosystemWalletComponents !== "function") return null;
|
|
622
728
|
try {
|
|
623
|
-
return
|
|
729
|
+
return activeUiKit.getEcosystemWalletComponents() ?? null;
|
|
624
730
|
} catch {
|
|
625
731
|
return null;
|
|
626
732
|
}
|
|
@@ -630,6 +736,10 @@ function useWalletComponents() {
|
|
|
630
736
|
//#region src/hooks/useDerivedAccountStatus.ts
|
|
631
737
|
const defaultAccountStatus = {
|
|
632
738
|
isConnected: false,
|
|
739
|
+
isConnecting: false,
|
|
740
|
+
isDisconnected: true,
|
|
741
|
+
isReconnecting: false,
|
|
742
|
+
status: "disconnected",
|
|
633
743
|
address: void 0,
|
|
634
744
|
chainId: void 0
|
|
635
745
|
};
|
|
@@ -644,6 +754,10 @@ function useDerivedAccountStatus() {
|
|
|
644
754
|
const accountHookOutput = walletFacadeHooks?.useAccount ? walletFacadeHooks.useAccount() : void 0;
|
|
645
755
|
if ((0, _openzeppelin_ui_utils.isRecordWithProperties)(accountHookOutput)) return {
|
|
646
756
|
isConnected: "isConnected" in accountHookOutput && typeof accountHookOutput.isConnected === "boolean" ? accountHookOutput.isConnected : defaultAccountStatus.isConnected,
|
|
757
|
+
isConnecting: "isConnecting" in accountHookOutput && typeof accountHookOutput.isConnecting === "boolean" ? accountHookOutput.isConnecting : defaultAccountStatus.isConnecting,
|
|
758
|
+
isDisconnected: "isDisconnected" in accountHookOutput && typeof accountHookOutput.isDisconnected === "boolean" ? accountHookOutput.isDisconnected : defaultAccountStatus.isDisconnected,
|
|
759
|
+
isReconnecting: "isReconnecting" in accountHookOutput && typeof accountHookOutput.isReconnecting === "boolean" ? accountHookOutput.isReconnecting : defaultAccountStatus.isReconnecting,
|
|
760
|
+
status: "status" in accountHookOutput && typeof accountHookOutput.status === "string" ? accountHookOutput.status : defaultAccountStatus.status,
|
|
647
761
|
address: "address" in accountHookOutput && typeof accountHookOutput.address === "string" ? accountHookOutput.address : defaultAccountStatus.address,
|
|
648
762
|
chainId: "chainId" in accountHookOutput && typeof accountHookOutput.chainId === "number" ? accountHookOutput.chainId : defaultAccountStatus.chainId
|
|
649
763
|
};
|
|
@@ -762,21 +876,21 @@ function useDerivedDisconnect() {
|
|
|
762
876
|
* This hook detects that scenario and invokes a callback to re-queue the network switch.
|
|
763
877
|
*
|
|
764
878
|
* @param selectedNetworkConfigId - Currently selected network in the app
|
|
765
|
-
* @param
|
|
879
|
+
* @param selectedCapability - Currently active wallet capability instance
|
|
766
880
|
* @param networkToSwitchTo - Current network switch queue state (null if no switch pending)
|
|
767
881
|
* @param onRequeueSwitch - Callback invoked when a network switch should be re-queued
|
|
768
882
|
*/
|
|
769
|
-
function useWalletReconnectionHandler(selectedNetworkConfigId,
|
|
883
|
+
function useWalletReconnectionHandler(selectedNetworkConfigId, selectedCapability, networkToSwitchTo, onRequeueSwitch) {
|
|
770
884
|
const { isConnected, chainId: walletChainId } = useDerivedAccountStatus();
|
|
771
885
|
const prevConnectedRef = (0, react.useRef)(isConnected);
|
|
772
886
|
(0, react.useEffect)(() => {
|
|
773
887
|
const isReconnection = !prevConnectedRef.current && isConnected;
|
|
774
888
|
prevConnectedRef.current = isConnected;
|
|
775
|
-
if (!isReconnection || !selectedNetworkConfigId || !
|
|
889
|
+
if (!isReconnection || !selectedNetworkConfigId || !selectedCapability) return;
|
|
776
890
|
if (networkToSwitchTo === selectedNetworkConfigId) return;
|
|
777
|
-
const
|
|
778
|
-
if (!("chainId" in
|
|
779
|
-
const targetChainId = Number(
|
|
891
|
+
const selectedNetworkConfig = selectedCapability.networkConfig;
|
|
892
|
+
if (!("chainId" in selectedNetworkConfig) || !walletChainId) return;
|
|
893
|
+
const targetChainId = Number(selectedNetworkConfig.chainId);
|
|
780
894
|
if (walletChainId !== targetChainId) {
|
|
781
895
|
_openzeppelin_ui_utils.logger.info("useWalletReconnectionHandler", `Wallet reconnected with chain ${walletChainId}, but selected network requires ${targetChainId}. Re-queueing switch.`);
|
|
782
896
|
onRequeueSwitch(selectedNetworkConfigId);
|
|
@@ -785,7 +899,7 @@ function useWalletReconnectionHandler(selectedNetworkConfigId, selectedAdapter,
|
|
|
785
899
|
isConnected,
|
|
786
900
|
walletChainId,
|
|
787
901
|
selectedNetworkConfigId,
|
|
788
|
-
|
|
902
|
+
selectedCapability,
|
|
789
903
|
networkToSwitchTo,
|
|
790
904
|
onRequeueSwitch
|
|
791
905
|
]);
|
|
@@ -817,37 +931,20 @@ function useWalletReconnectionHandler(selectedNetworkConfigId, selectedAdapter,
|
|
|
817
931
|
*/
|
|
818
932
|
const WalletConnectionUI = ({ className, connectButtonProps, accountDisplayProps, networkSwitcherProps }) => {
|
|
819
933
|
const [isError, setIsError] = (0, react.useState)(false);
|
|
820
|
-
const {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
adapterId: activeAdapter?.networkConfig.id,
|
|
824
|
-
hasFacadeHooks: !!walletFacadeHooks
|
|
825
|
-
});
|
|
826
|
-
}, [activeAdapter, walletFacadeHooks]);
|
|
934
|
+
const { activeNetworkConfig, activeRuntime, isRuntimeLoading } = useWalletState();
|
|
935
|
+
const activeUiKit = activeRuntime?.uiKit;
|
|
936
|
+
if (!!(isRuntimeLoading && activeRuntime?.networkConfig?.ecosystem && activeNetworkConfig?.ecosystem && activeRuntime.networkConfig.ecosystem !== activeNetworkConfig.ecosystem)) return null;
|
|
827
937
|
const walletComponents = (() => {
|
|
828
|
-
if (!
|
|
829
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionUI", "[Debug] No activeAdapter or getEcosystemWalletComponents method, returning null.");
|
|
830
|
-
return null;
|
|
831
|
-
}
|
|
938
|
+
if (!activeUiKit || typeof activeUiKit.getEcosystemWalletComponents !== "function") return null;
|
|
832
939
|
try {
|
|
833
|
-
|
|
834
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionUI", "[Debug] walletComponents from adapter:", components);
|
|
835
|
-
return components;
|
|
940
|
+
return activeUiKit.getEcosystemWalletComponents();
|
|
836
941
|
} catch (error) {
|
|
837
|
-
_openzeppelin_ui_utils.logger.error("WalletConnectionUI", "
|
|
942
|
+
_openzeppelin_ui_utils.logger.error("WalletConnectionUI", "Error getting wallet components:", error);
|
|
838
943
|
setIsError(true);
|
|
839
944
|
return null;
|
|
840
945
|
}
|
|
841
946
|
})();
|
|
842
|
-
if (!walletComponents)
|
|
843
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionUI", "[Debug] getEcosystemWalletComponents returned null/undefined, rendering null.");
|
|
844
|
-
return null;
|
|
845
|
-
}
|
|
846
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionUI", "Rendering wallet components:", {
|
|
847
|
-
hasConnectButton: !!walletComponents.ConnectButton,
|
|
848
|
-
hasAccountDisplay: !!walletComponents.AccountDisplay,
|
|
849
|
-
hasNetworkSwitcher: !!walletComponents.NetworkSwitcher
|
|
850
|
-
});
|
|
947
|
+
if (!walletComponents) return null;
|
|
851
948
|
const { ConnectButton, AccountDisplay, NetworkSwitcher } = walletComponents;
|
|
852
949
|
if (isError) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
853
950
|
className: (0, _openzeppelin_ui_utils.cn)("flex items-center gap-4", className),
|
|
@@ -875,18 +972,8 @@ const WalletConnectionUI = ({ className, connectButtonProps, accountDisplayProps
|
|
|
875
972
|
* Uses useWalletState to get its data.
|
|
876
973
|
*/
|
|
877
974
|
const WalletConnectionHeader = () => {
|
|
878
|
-
const {
|
|
879
|
-
(0,
|
|
880
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionHeader", "[Debug] State from useWalletState:", {
|
|
881
|
-
adapterPresent: !!activeAdapter,
|
|
882
|
-
adapterNetwork: activeAdapter?.networkConfig.id,
|
|
883
|
-
isLoading: isAdapterLoading
|
|
884
|
-
});
|
|
885
|
-
}, [activeAdapter, isAdapterLoading]);
|
|
886
|
-
if (isAdapterLoading) {
|
|
887
|
-
_openzeppelin_ui_utils.logger.debug("WalletConnectionHeader", "[Debug] Adapter loading, showing skeleton.");
|
|
888
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-28 animate-pulse rounded bg-muted" });
|
|
889
|
-
}
|
|
975
|
+
const { isRuntimeLoading } = useWalletState();
|
|
976
|
+
if (isRuntimeLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-28 animate-pulse rounded bg-muted" });
|
|
890
977
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WalletConnectionUI, {});
|
|
891
978
|
};
|
|
892
979
|
|
|
@@ -906,7 +993,7 @@ const WalletConnectionHeader = () => {
|
|
|
906
993
|
* - Tracks switch attempts to prevent duplicate operations
|
|
907
994
|
* - Provides completion callback for parent components to handle state cleanup
|
|
908
995
|
*/
|
|
909
|
-
const NetworkSwitchManager = ({
|
|
996
|
+
const NetworkSwitchManager = ({ wallet, networkCatalog, targetNetworkId, onNetworkSwitchComplete }) => {
|
|
910
997
|
const isMountedRef = (0, react.useRef)(true);
|
|
911
998
|
const [hasAttemptedSwitch, setHasAttemptedSwitch] = (0, react.useState)(false);
|
|
912
999
|
const { isConnected, chainId: currentChainIdFromHook } = useDerivedAccountStatus();
|
|
@@ -923,7 +1010,7 @@ const NetworkSwitchManager = ({ adapter, targetNetworkId, onNetworkSwitchComplet
|
|
|
923
1010
|
(0, react.useEffect)(() => {
|
|
924
1011
|
_openzeppelin_ui_utils.logger.info("NetworkSwitchManager", "State Update:", {
|
|
925
1012
|
target: targetNetworkId,
|
|
926
|
-
|
|
1013
|
+
walletNetwork: wallet.networkConfig.id,
|
|
927
1014
|
isSwitching: isSwitchingNetworkViaHook,
|
|
928
1015
|
hookError: !!switchNetworkError,
|
|
929
1016
|
canExec: !!execSwitchNetwork,
|
|
@@ -932,7 +1019,7 @@ const NetworkSwitchManager = ({ adapter, targetNetworkId, onNetworkSwitchComplet
|
|
|
932
1019
|
attempted: hasAttemptedSwitch
|
|
933
1020
|
});
|
|
934
1021
|
}, [
|
|
935
|
-
|
|
1022
|
+
wallet,
|
|
936
1023
|
targetNetworkId,
|
|
937
1024
|
isSwitchingNetworkViaHook,
|
|
938
1025
|
switchNetworkError,
|
|
@@ -959,19 +1046,23 @@ const NetworkSwitchManager = ({ adapter, targetNetworkId, onNetworkSwitchComplet
|
|
|
959
1046
|
_openzeppelin_ui_utils.logger.info("NetworkSwitchManager", "Previous switch attempt concluded. Deferring to completion effect.");
|
|
960
1047
|
return;
|
|
961
1048
|
}
|
|
962
|
-
if (
|
|
963
|
-
completeOperation(`
|
|
1049
|
+
if (!networkCatalog.getNetworks().find((network) => network.id === targetNetworkId)) {
|
|
1050
|
+
completeOperation(`Target network ${targetNetworkId} is not present in the network catalog.`, { notifyComplete: false });
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
if (wallet.networkConfig.id !== targetNetworkId) {
|
|
1054
|
+
completeOperation(`CRITICAL: Wallet capability (${wallet.networkConfig.id}) vs Target (${targetNetworkId}) mismatch. Operation halted.`, { notifyComplete: false });
|
|
964
1055
|
return;
|
|
965
1056
|
}
|
|
966
1057
|
if (!isConnected) {
|
|
967
1058
|
completeOperation("Wallet not connected (derived status). Awaiting connection.", { notifyComplete: false });
|
|
968
1059
|
return;
|
|
969
1060
|
}
|
|
970
|
-
if (!("chainId" in
|
|
1061
|
+
if (!("chainId" in wallet.networkConfig)) {
|
|
971
1062
|
completeOperation("Network does not support chain switching (non-EVM). Operation complete (no-op).");
|
|
972
1063
|
return;
|
|
973
1064
|
}
|
|
974
|
-
const targetChainToBeSwitchedTo = Number(
|
|
1065
|
+
const targetChainToBeSwitchedTo = Number(wallet.networkConfig.chainId);
|
|
975
1066
|
if (currentChainIdFromHook === targetChainToBeSwitchedTo) {
|
|
976
1067
|
completeOperation("Already on correct chain (derived status). Operation complete.");
|
|
977
1068
|
return;
|
|
@@ -988,7 +1079,8 @@ const NetworkSwitchManager = ({ adapter, targetNetworkId, onNetworkSwitchComplet
|
|
|
988
1079
|
const timeoutId = setTimeout(performSwitchActual, 100);
|
|
989
1080
|
return () => clearTimeout(timeoutId);
|
|
990
1081
|
}, [
|
|
991
|
-
|
|
1082
|
+
wallet,
|
|
1083
|
+
networkCatalog,
|
|
992
1084
|
targetNetworkId,
|
|
993
1085
|
execSwitchNetwork,
|
|
994
1086
|
isSwitchingNetworkViaHook,
|
|
@@ -1020,23 +1112,23 @@ const NetworkSwitchManager = ({ adapter, targetNetworkId, onNetworkSwitchComplet
|
|
|
1020
1112
|
};
|
|
1021
1113
|
|
|
1022
1114
|
//#endregion
|
|
1023
|
-
exports.AdapterContext = AdapterContext;
|
|
1024
|
-
exports.AdapterProvider = AdapterProvider;
|
|
1025
1115
|
exports.AnalyticsContext = AnalyticsContext;
|
|
1026
1116
|
exports.AnalyticsProvider = AnalyticsProvider;
|
|
1027
1117
|
exports.NetworkSwitchManager = NetworkSwitchManager;
|
|
1118
|
+
exports.RuntimeContext = RuntimeContext;
|
|
1119
|
+
exports.RuntimeProvider = RuntimeProvider;
|
|
1028
1120
|
exports.VERSION = VERSION;
|
|
1029
1121
|
exports.WalletConnectionHeader = WalletConnectionHeader;
|
|
1030
1122
|
exports.WalletConnectionUI = WalletConnectionUI;
|
|
1031
1123
|
exports.WalletStateContext = WalletStateContext;
|
|
1032
1124
|
exports.WalletStateProvider = WalletStateProvider;
|
|
1033
|
-
exports.useAdapterContext = useAdapterContext;
|
|
1034
1125
|
exports.useAnalytics = useAnalytics;
|
|
1035
1126
|
exports.useDerivedAccountStatus = useDerivedAccountStatus;
|
|
1036
1127
|
exports.useDerivedChainInfo = useDerivedChainInfo;
|
|
1037
1128
|
exports.useDerivedConnectStatus = useDerivedConnectStatus;
|
|
1038
1129
|
exports.useDerivedDisconnect = useDerivedDisconnect;
|
|
1039
1130
|
exports.useDerivedSwitchChainStatus = useDerivedSwitchChainStatus;
|
|
1131
|
+
exports.useRuntimeContext = useRuntimeContext;
|
|
1040
1132
|
exports.useWalletComponents = useWalletComponents;
|
|
1041
1133
|
exports.useWalletReconnectionHandler = useWalletReconnectionHandler;
|
|
1042
1134
|
exports.useWalletState = useWalletState;
|