@openzeppelin/ui-builder-adapter-evm 1.2.0 → 1.4.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/README.md +33 -18
- package/dist/index.cjs +4651 -4448
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -226
- package/dist/index.d.ts +12 -226
- package/dist/index.js +4737 -4535
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
- package/src/__tests__/adapter-parsing.test.ts +4 -3
- package/src/__tests__/getDefaultServiceConfig.test.ts +185 -0
- package/src/__tests__/mocks/mock-network-configs.ts +1 -1
- package/src/__tests__/provenanceLinks.test.ts +6 -4
- package/src/__tests__/providerSelection.test.ts +5 -4
- package/src/__tests__/timeouts.test.ts +5 -3
- package/src/__tests__/wallet-connect.test.ts +2 -2
- package/src/adapter.ts +61 -107
- package/src/configuration/execution.ts +1 -52
- package/src/configuration/index.ts +2 -3
- package/src/configuration/network-services.ts +47 -60
- package/src/index.ts +22 -13
- package/src/networks/index.ts +2 -1
- package/src/networks/mainnet.ts +1 -1
- package/src/networks/testnet.ts +1 -1
- package/src/query/adapter-query.ts +72 -0
- package/src/query/index.ts +2 -2
- package/src/transaction/components/useEvmRelayerOptions.ts +5 -3
- package/src/transaction/index.ts +1 -5
- package/src/types/artifacts.ts +5 -30
- package/src/types/providers.ts +7 -18
- package/src/wallet/components/EvmWalletUiRoot.tsx +1 -1
- package/src/wallet/evmUiKitManager.ts +26 -129
- package/src/wallet/hooks/index.ts +0 -1
- package/src/wallet/implementation/wagmi-implementation.ts +45 -577
- package/src/wallet/index.ts +2 -3
- package/src/wallet/rainbowkit/__tests__/export-service.test.ts +1 -2
- package/src/wallet/rainbowkit/componentFactory.ts +10 -8
- package/src/wallet/rainbowkit/components.tsx +16 -133
- package/src/wallet/rainbowkit/index.ts +27 -5
- package/src/wallet/utils/__tests__/uiKitService.test.ts +5 -1
- package/src/wallet/utils/connection.ts +8 -52
- package/src/wallet/utils/index.ts +0 -2
- package/src/wallet/utils/uiKitService.ts +7 -3
- package/src/wallet/utils/walletImplementationManager.ts +5 -4
- package/src/wallet/utils.ts +1 -65
- package/src/abi/__tests__/etherscan-v2.test.ts +0 -117
- package/src/abi/__tests__/transformer.test.ts +0 -342
- package/src/abi/comparison.ts +0 -389
- package/src/abi/etherscan-v2.ts +0 -243
- package/src/abi/etherscan.ts +0 -158
- package/src/abi/index.ts +0 -7
- package/src/abi/loader.ts +0 -415
- package/src/abi/sourcify.ts +0 -75
- package/src/abi/transformer.ts +0 -163
- package/src/abi/types.ts +0 -101
- package/src/configuration/__tests__/explorer.test.ts +0 -174
- package/src/configuration/__tests__/rpc.test.ts +0 -176
- package/src/configuration/explorer.ts +0 -243
- package/src/configuration/rpc.ts +0 -257
- package/src/mapping/__tests__/field-generator.test.ts +0 -137
- package/src/mapping/__tests__/type-mapper.test.ts +0 -139
- package/src/mapping/constants.ts +0 -57
- package/src/mapping/field-generator.ts +0 -115
- package/src/mapping/index.ts +0 -4
- package/src/mapping/type-mapper.ts +0 -80
- package/src/proxy/detection.ts +0 -465
- package/src/query/handler.ts +0 -227
- package/src/query/view-checker.ts +0 -10
- package/src/transaction/eoa.ts +0 -98
- package/src/transaction/execution-strategy.ts +0 -33
- package/src/transaction/formatter.ts +0 -101
- package/src/transaction/relayer.ts +0 -380
- package/src/transaction/sender.ts +0 -185
- package/src/transform/index.ts +0 -3
- package/src/transform/input-parser.ts +0 -177
- package/src/transform/output-formatter.ts +0 -64
- package/src/types/__tests__/artifacts.test.ts +0 -105
- package/src/types.ts +0 -92
- package/src/utils/__tests__/artifacts.test.ts +0 -81
- package/src/utils/artifacts.ts +0 -30
- package/src/utils/formatting.ts +0 -25
- package/src/utils/gas.ts +0 -17
- package/src/utils/index.ts +0 -6
- package/src/utils/json.ts +0 -19
- package/src/utils/validation.ts +0 -10
- package/src/validation/eoa.ts +0 -33
- package/src/validation/index.ts +0 -2
- package/src/validation/relayer.ts +0 -13
- package/src/wallet/__tests__/utils.test.ts +0 -149
- package/src/wallet/components/account/AccountDisplay.tsx +0 -52
- package/src/wallet/components/connect/ConnectButton.tsx +0 -125
- package/src/wallet/components/connect/ConnectorDialog.tsx +0 -140
- package/src/wallet/components/index.ts +0 -4
- package/src/wallet/components/network/NetworkSwitcher.tsx +0 -90
- package/src/wallet/context/index.ts +0 -1
- package/src/wallet/context/wagmi-context.tsx +0 -7
- package/src/wallet/hooks/useIsWagmiProviderInitialized.ts +0 -11
- package/src/wallet/rainbowkit/config-generator.ts +0 -56
- package/src/wallet/rainbowkit/config-service.ts +0 -169
- package/src/wallet/rainbowkit/export-service.ts +0 -18
- package/src/wallet/rainbowkit/rainbowkitAssetManager.ts +0 -74
- package/src/wallet/rainbowkit/types.ts +0 -74
- package/src/wallet/rainbowkit/utils.ts +0 -96
- package/src/wallet/services/configResolutionService.ts +0 -65
- package/src/wallet/utils/SafeWagmiComponent.tsx +0 -72
- package/src/wallet/utils/filterWalletComponents.ts +0 -89
|
@@ -1,599 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* EVM Wagmi Wallet Implementation
|
|
3
3
|
*
|
|
4
|
-
* This file
|
|
5
|
-
*
|
|
4
|
+
* This file configures and exports the core WagmiWalletImplementation
|
|
5
|
+
* with EVM-specific settings.
|
|
6
6
|
*/
|
|
7
|
-
import { injected, metaMask, safe, walletConnect } from '@wagmi/connectors';
|
|
8
7
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
switchChain,
|
|
16
|
-
watchAccount,
|
|
17
|
-
type Config,
|
|
18
|
-
type GetAccountReturnType,
|
|
19
|
-
type CreateConnectorFn as WagmiCreateConnectorFn,
|
|
20
|
-
} from '@wagmi/core';
|
|
21
|
-
import { http, PublicClient, WalletClient, type Chain } from 'viem';
|
|
8
|
+
WagmiWalletImplementation as CoreWagmiWalletImplementation,
|
|
9
|
+
getWagmiConfigForRainbowKit,
|
|
10
|
+
type WagmiConfigChains,
|
|
11
|
+
type WagmiWalletConfig,
|
|
12
|
+
} from '@openzeppelin/ui-builder-adapter-evm-core';
|
|
13
|
+
import type { UiKitConfiguration } from '@openzeppelin/ui-types';
|
|
22
14
|
|
|
23
|
-
import type { Connector, UiKitConfiguration } from '@openzeppelin/ui-types';
|
|
24
|
-
import { appConfigService, logger } from '@openzeppelin/ui-utils';
|
|
25
|
-
|
|
26
|
-
import { getUserRpcUrl } from '../../configuration/rpc';
|
|
27
15
|
import { evmNetworks } from '../../networks';
|
|
28
|
-
import { getWagmiConfigForRainbowKit } from '../rainbowkit';
|
|
29
|
-
import { type WagmiConfigChains } from '../types';
|
|
30
|
-
|
|
31
|
-
const LOG_SYSTEM = 'WagmiWalletImplementation'; // Define LOG_SYSTEM here
|
|
32
16
|
|
|
33
17
|
/**
|
|
34
|
-
* Generates the supported chains
|
|
18
|
+
* Generates the supported chains from EVM network configurations.
|
|
35
19
|
* Only includes networks that have a viemChain property (ensuring wagmi compatibility).
|
|
36
|
-
* This ensures that wagmi only supports networks that are defined in mainnet.ts and testnet.ts.
|
|
37
20
|
*/
|
|
38
|
-
const getSupportedChainsFromNetworks = ()
|
|
39
|
-
|
|
40
|
-
.filter((network) => network.viemChain)
|
|
21
|
+
const getSupportedChainsFromNetworks = () => {
|
|
22
|
+
return evmNetworks
|
|
23
|
+
.filter((network) => network.viemChain)
|
|
41
24
|
.map((network) => network.viemChain!)
|
|
42
|
-
.filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index);
|
|
43
|
-
|
|
44
|
-
logger.info(
|
|
45
|
-
LOG_SYSTEM,
|
|
46
|
-
`Generated supported chains from network configurations: ${chains.length} chains`,
|
|
47
|
-
chains.map((c) => ({ id: c.id, name: c.name }))
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
return chains;
|
|
25
|
+
.filter((chain, index, self) => self.findIndex((c) => c.id === chain.id) === index);
|
|
51
26
|
};
|
|
52
27
|
|
|
53
28
|
/**
|
|
54
|
-
*
|
|
55
|
-
* This mapping is auto-generated from the EVM network configurations.
|
|
29
|
+
* The supported chains for EVM adapter.
|
|
56
30
|
*/
|
|
57
|
-
const
|
|
58
|
-
const mapping = evmNetworks
|
|
59
|
-
.filter((network) => network.viemChain) // Only include networks with viemChain
|
|
60
|
-
.reduce(
|
|
61
|
-
(acc, network) => {
|
|
62
|
-
acc[network.chainId] = network.id;
|
|
63
|
-
return acc;
|
|
64
|
-
},
|
|
65
|
-
{} as Record<number, string>
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
logger.info(
|
|
69
|
-
LOG_SYSTEM,
|
|
70
|
-
'Generated chain ID to network ID mapping from network configurations:',
|
|
71
|
-
mapping
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
return mapping;
|
|
75
|
-
};
|
|
31
|
+
const defaultSupportedChains = getSupportedChainsFromNetworks();
|
|
76
32
|
|
|
77
33
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Auto-generated mapping from Viem chain IDs to application network IDs.
|
|
85
|
-
* This mapping is essential for AppConfigService to look up RPC URL overrides.
|
|
86
|
-
* It's automatically synchronized with the networks defined in mainnet.ts and testnet.ts.
|
|
87
|
-
*/
|
|
88
|
-
const viemChainIdToAppNetworkId: Record<number, string> = getChainIdToNetworkIdMapping();
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Class responsible for encapsulating Wagmi core logic for wallet interactions.
|
|
92
|
-
* This class should not be used directly by UI components. The EvmAdapter
|
|
93
|
-
* exposes a standardized interface for wallet operations.
|
|
94
|
-
* It manages Wagmi Config instances and provides methods for wallet actions.
|
|
34
|
+
* Create an EVM-configured WagmiWalletImplementation instance.
|
|
35
|
+
*
|
|
36
|
+
* @param walletConnectProjectId - Optional WalletConnect project ID
|
|
37
|
+
* @param initialUiKitConfig - Optional initial UI kit configuration
|
|
38
|
+
* @returns A configured WagmiWalletImplementation instance
|
|
95
39
|
*/
|
|
96
|
-
export
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
initialUiKitConfig?.kitName
|
|
119
|
-
);
|
|
120
|
-
this.initialized = true;
|
|
121
|
-
logger.info(
|
|
122
|
-
LOG_SYSTEM,
|
|
123
|
-
'WagmiWalletImplementation instance initialized (Wagmi config creation deferred).'
|
|
124
|
-
);
|
|
125
|
-
// Subscribe to RPC configuration changes to invalidate cached config
|
|
126
|
-
this.setupRpcConfigListener();
|
|
127
|
-
// No config created here by default anymore.
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Sets up a listener for RPC configuration changes to invalidate the cached Wagmi config
|
|
132
|
-
* when user changes RPC settings.
|
|
133
|
-
*/
|
|
134
|
-
private setupRpcConfigListener(): void {
|
|
135
|
-
// Import dynamically to avoid circular dependencies
|
|
136
|
-
import('@openzeppelin/ui-utils')
|
|
137
|
-
.then(({ userRpcConfigService }) => {
|
|
138
|
-
// Subscribe to all RPC config changes
|
|
139
|
-
this.rpcConfigUnsubscribe = userRpcConfigService.subscribe('*', (event) => {
|
|
140
|
-
if (event.type === 'rpc-config-changed' || event.type === 'rpc-config-cleared') {
|
|
141
|
-
logger.info(
|
|
142
|
-
LOG_SYSTEM,
|
|
143
|
-
`RPC config changed for network ${event.networkId}. Invalidating cached Wagmi config.`
|
|
144
|
-
);
|
|
145
|
-
// Invalidate the cached config to force recreation with new RPC settings
|
|
146
|
-
this.defaultInstanceConfig = null;
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
})
|
|
150
|
-
.catch((error) => {
|
|
151
|
-
logger.error(LOG_SYSTEM, 'Failed to setup RPC config listener:', error);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Cleanup method to unsubscribe from RPC config changes
|
|
157
|
-
*/
|
|
158
|
-
public cleanup(): void {
|
|
159
|
-
if (this.rpcConfigUnsubscribe) {
|
|
160
|
-
this.rpcConfigUnsubscribe();
|
|
161
|
-
this.rpcConfigUnsubscribe = undefined;
|
|
162
|
-
}
|
|
163
|
-
if (this.unsubscribe) {
|
|
164
|
-
this.unsubscribe();
|
|
165
|
-
this.unsubscribe = undefined;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Sets the externally determined, currently active WagmiConfig instance.
|
|
171
|
-
* This is typically called by EvmUiKitManager after it has resolved the appropriate
|
|
172
|
-
* config for the selected UI kit (e.g., RainbowKit's config or a default custom config).
|
|
173
|
-
* @param config - The Wagmi Config object to set as active, or null to clear it.
|
|
174
|
-
*/
|
|
175
|
-
public setActiveWagmiConfig(config: Config | null): void {
|
|
176
|
-
logger.info(
|
|
177
|
-
LOG_SYSTEM,
|
|
178
|
-
'setActiveWagmiConfig called with config:',
|
|
179
|
-
config ? 'Valid Config' : 'Null'
|
|
180
|
-
);
|
|
181
|
-
this.activeWagmiConfig = config;
|
|
182
|
-
|
|
183
|
-
// If the activeWagmiConfig instance has changed and there was an existing direct subscription
|
|
184
|
-
// via onWalletConnectionChange, that subscription was bound to the *previous* config instance.
|
|
185
|
-
// It might now be stale or not receive updates reflecting the new config context.
|
|
186
|
-
// Consumers relying on onWalletConnectionChange for live updates across fundamental config changes
|
|
187
|
-
// (e.g., switching UI kits or major network group changes affecting the config instance)
|
|
188
|
-
// may need to re-invoke onWalletConnectionChange to get a new subscription bound to the new config.
|
|
189
|
-
// UI components should primarily rely on useWalletState and derived hooks for reactivity,
|
|
190
|
-
// which will naturally update with the new adapter/config context.
|
|
191
|
-
if (this.unsubscribe) {
|
|
192
|
-
logger.warn(
|
|
193
|
-
LOG_SYSTEM,
|
|
194
|
-
'setActiveWagmiConfig: Active WagmiConfig instance has changed. Existing direct watchAccount subscription (via onWalletConnectionChange) may be stale and operating on an old config instance.'
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Creates a default WagmiConfig instance on demand.
|
|
201
|
-
* This configuration includes standard connectors (injected, MetaMask, Safe)
|
|
202
|
-
* and WalletConnect if a project ID is available.
|
|
203
|
-
* Used as a fallback or for 'custom' UI kit mode.
|
|
204
|
-
* @returns A Wagmi Config object.
|
|
205
|
-
*/
|
|
206
|
-
private createDefaultConfig(): Config {
|
|
207
|
-
const baseConnectors: WagmiCreateConnectorFn[] = [injected(), metaMask(), safe()];
|
|
208
|
-
if (this.walletConnectProjectId?.trim()) {
|
|
209
|
-
baseConnectors.push(walletConnect({ projectId: this.walletConnectProjectId }));
|
|
210
|
-
logger.info(LOG_SYSTEM, 'WalletConnect connector added to DEFAULT config.');
|
|
211
|
-
} else {
|
|
212
|
-
logger.warn(
|
|
213
|
-
LOG_SYSTEM,
|
|
214
|
-
'WalletConnect Project ID not provided; WC connector unavailable for DEFAULT config.'
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
const transportsConfig = defaultSupportedChains.reduce(
|
|
218
|
-
(acc, chainDefinition) => {
|
|
219
|
-
let rpcUrlToUse: string | undefined = chainDefinition.rpcUrls.default?.http?.[0];
|
|
220
|
-
const appNetworkIdString = viemChainIdToAppNetworkId[chainDefinition.id];
|
|
221
|
-
if (appNetworkIdString) {
|
|
222
|
-
// Prefer user-configured RPC from generic service
|
|
223
|
-
let httpRpcOverride: string | undefined = getUserRpcUrl(appNetworkIdString);
|
|
224
|
-
// Fallback to AppConfigService override if no user config
|
|
225
|
-
if (!httpRpcOverride) {
|
|
226
|
-
const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(appNetworkIdString);
|
|
227
|
-
if (typeof rpcOverrideSetting === 'string') {
|
|
228
|
-
httpRpcOverride = rpcOverrideSetting;
|
|
229
|
-
} else if (typeof rpcOverrideSetting === 'object') {
|
|
230
|
-
// Handle both RpcEndpointConfig and UserRpcProviderConfig
|
|
231
|
-
if ('http' in rpcOverrideSetting && rpcOverrideSetting.http) {
|
|
232
|
-
httpRpcOverride = rpcOverrideSetting.http;
|
|
233
|
-
} else if ('url' in rpcOverrideSetting && rpcOverrideSetting.url) {
|
|
234
|
-
httpRpcOverride = rpcOverrideSetting.url;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (httpRpcOverride) {
|
|
239
|
-
logger.info(
|
|
240
|
-
LOG_SYSTEM,
|
|
241
|
-
`Using overridden RPC for chain ${chainDefinition.name} (default config): ${httpRpcOverride}`
|
|
242
|
-
);
|
|
243
|
-
rpcUrlToUse = httpRpcOverride;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
acc[chainDefinition.id] = http(rpcUrlToUse);
|
|
247
|
-
return acc;
|
|
248
|
-
},
|
|
249
|
-
{} as Record<number, ReturnType<typeof http>>
|
|
250
|
-
);
|
|
251
|
-
try {
|
|
252
|
-
const defaultConfig = createConfig({
|
|
253
|
-
chains: defaultSupportedChains as unknown as WagmiConfigChains,
|
|
254
|
-
connectors: baseConnectors,
|
|
255
|
-
transports: transportsConfig,
|
|
256
|
-
});
|
|
257
|
-
logger.info(LOG_SYSTEM, 'Default Wagmi config created successfully on demand.');
|
|
258
|
-
return defaultConfig;
|
|
259
|
-
} catch (error) {
|
|
260
|
-
logger.error(LOG_SYSTEM, 'Error creating default Wagmi config on demand:', error);
|
|
261
|
-
return createConfig({
|
|
262
|
-
chains: [defaultSupportedChains[0]] as unknown as WagmiConfigChains,
|
|
263
|
-
connectors: [injected()],
|
|
264
|
-
transports: { [defaultSupportedChains[0].id]: http() },
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Wrapper function to convert AppConfigService RPC overrides to the format expected by RainbowKit.
|
|
271
|
-
* @param networkId - The network ID to get RPC override for
|
|
272
|
-
* @returns RPC configuration in the format expected by RainbowKit
|
|
273
|
-
*/
|
|
274
|
-
private getRpcOverrideForRainbowKit(
|
|
275
|
-
networkId: string
|
|
276
|
-
): string | { http?: string; ws?: string } | undefined {
|
|
277
|
-
// Prefer user-configured RPC from generic service first
|
|
278
|
-
const userRpcUrl = getUserRpcUrl(networkId);
|
|
279
|
-
if (userRpcUrl) {
|
|
280
|
-
return { http: userRpcUrl };
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const rpcOverrideSetting = appConfigService.getRpcEndpointOverride(networkId);
|
|
284
|
-
|
|
285
|
-
if (typeof rpcOverrideSetting === 'string') {
|
|
286
|
-
return rpcOverrideSetting;
|
|
287
|
-
} else if (typeof rpcOverrideSetting === 'object' && rpcOverrideSetting !== null) {
|
|
288
|
-
// Check for UserRpcProviderConfig first
|
|
289
|
-
if ('url' in rpcOverrideSetting && typeof rpcOverrideSetting.url === 'string') {
|
|
290
|
-
// It's a UserRpcProviderConfig - convert url to http
|
|
291
|
-
return {
|
|
292
|
-
http: rpcOverrideSetting.url,
|
|
293
|
-
};
|
|
294
|
-
} else if ('http' in rpcOverrideSetting || 'ws' in rpcOverrideSetting) {
|
|
295
|
-
// It's an RpcEndpointConfig
|
|
296
|
-
const config = rpcOverrideSetting as { http?: string; ws?: string };
|
|
297
|
-
return {
|
|
298
|
-
http: config.http,
|
|
299
|
-
ws: config.ws,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return undefined;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Retrieves or creates the WagmiConfig specifically for RainbowKit.
|
|
309
|
-
* This delegates to `getWagmiConfigForRainbowKit` service which handles caching
|
|
310
|
-
* and uses RainbowKit's `getDefaultConfig`.
|
|
311
|
-
* @param currentAdapterUiKitConfig - The fully resolved UI kit configuration for the adapter.
|
|
312
|
-
* @returns A Promise resolving to the RainbowKit-specific Wagmi Config object, or null if creation fails or not RainbowKit.
|
|
313
|
-
*/
|
|
314
|
-
public async getConfigForRainbowKit(
|
|
315
|
-
currentAdapterUiKitConfig: UiKitConfiguration
|
|
316
|
-
): Promise<Config | null> {
|
|
317
|
-
if (!this.initialized) {
|
|
318
|
-
logger.error(
|
|
319
|
-
LOG_SYSTEM,
|
|
320
|
-
'getConfigForRainbowKit called before implementation initialization.'
|
|
321
|
-
);
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
if (currentAdapterUiKitConfig?.kitName !== 'rainbowkit') {
|
|
325
|
-
logger.warn(
|
|
326
|
-
LOG_SYSTEM,
|
|
327
|
-
'getConfigForRainbowKit called, but kitName is not rainbowkit. Returning null.'
|
|
328
|
-
);
|
|
329
|
-
return null;
|
|
330
|
-
}
|
|
331
|
-
logger.info(
|
|
332
|
-
LOG_SYSTEM,
|
|
333
|
-
'getConfigForRainbowKit: Kit is RainbowKit. Proceeding to create/get config. CurrentAdapterUiKitConfig:',
|
|
334
|
-
currentAdapterUiKitConfig
|
|
335
|
-
);
|
|
336
|
-
const rainbowKitWagmiConfig = await getWagmiConfigForRainbowKit(
|
|
337
|
-
currentAdapterUiKitConfig,
|
|
338
|
-
defaultSupportedChains as WagmiConfigChains,
|
|
339
|
-
viemChainIdToAppNetworkId,
|
|
340
|
-
this.getRpcOverrideForRainbowKit.bind(this)
|
|
341
|
-
);
|
|
342
|
-
if (rainbowKitWagmiConfig) {
|
|
343
|
-
logger.info(LOG_SYSTEM, 'Returning RainbowKit-specific Wagmi config for provider.');
|
|
344
|
-
return rainbowKitWagmiConfig;
|
|
345
|
-
}
|
|
346
|
-
logger.warn(LOG_SYSTEM, 'RainbowKit specific Wagmi config creation failed.');
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Determines and returns the WagmiConfig to be used by EvmUiKitManager during its configuration process.
|
|
352
|
-
* If RainbowKit is specified in the passed uiKitConfig, it attempts to get its specific config.
|
|
353
|
-
* Otherwise, it falls back to creating/returning a default instance config.
|
|
354
|
-
* @param uiKitConfig - The fully resolved UiKitConfiguration that the manager is currently processing.
|
|
355
|
-
* @returns A Promise resolving to the determined Wagmi Config object.
|
|
356
|
-
*/
|
|
357
|
-
public async getActiveConfigForManager(uiKitConfig: UiKitConfiguration): Promise<Config> {
|
|
358
|
-
if (!this.initialized) {
|
|
359
|
-
logger.error(
|
|
360
|
-
LOG_SYSTEM,
|
|
361
|
-
'getActiveConfigForManager called before initialization! Creating fallback.'
|
|
362
|
-
);
|
|
363
|
-
return createConfig({
|
|
364
|
-
chains: [defaultSupportedChains[0]] as unknown as WagmiConfigChains,
|
|
365
|
-
transports: { [defaultSupportedChains[0].id]: http() },
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (uiKitConfig?.kitName === 'rainbowkit') {
|
|
370
|
-
const rkConfig = await this.getConfigForRainbowKit(uiKitConfig);
|
|
371
|
-
if (rkConfig) return rkConfig;
|
|
372
|
-
logger.warn(
|
|
373
|
-
LOG_SYSTEM,
|
|
374
|
-
'getActiveConfigForManager: RainbowKit config failed, falling back to default.'
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Reuse existing default config if available, only create if needed
|
|
379
|
-
// This ensures wallet connection state is preserved across network switches
|
|
380
|
-
// Config is automatically invalidated when RPC settings change via setupRpcConfigListener()
|
|
381
|
-
if (!this.defaultInstanceConfig) {
|
|
382
|
-
this.defaultInstanceConfig = this.createDefaultConfig();
|
|
383
|
-
}
|
|
384
|
-
return this.defaultInstanceConfig;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* @deprecated Prefer using methods that rely on the externally set `activeWagmiConfig`
|
|
389
|
-
* or methods that determine contextually appropriate config like `getActiveConfigForManager` (for manager use)
|
|
390
|
-
* or ensure `activeWagmiConfig` is set before calling wagmi actions.
|
|
391
|
-
* This method returns the internally cached default config or the active one if set.
|
|
392
|
-
* @returns The current default or active Wagmi Config object.
|
|
393
|
-
*/
|
|
394
|
-
public getConfig(): Config {
|
|
395
|
-
logger.warn(
|
|
396
|
-
LOG_SYSTEM,
|
|
397
|
-
'getConfig() is deprecated. Internal calls should use activeWagmiConfig if set, or ensure default is created.'
|
|
398
|
-
);
|
|
399
|
-
if (this.activeWagmiConfig) return this.activeWagmiConfig;
|
|
400
|
-
if (!this.defaultInstanceConfig) {
|
|
401
|
-
this.defaultInstanceConfig = this.createDefaultConfig();
|
|
402
|
-
}
|
|
403
|
-
return this.defaultInstanceConfig!;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Gets the current wallet connection status (isConnected, address, chainId, etc.).
|
|
408
|
-
* This is a synchronous operation and uses the `activeWagmiConfig` if set by `EvmUiKitManager`,
|
|
409
|
-
* otherwise falls back to the default instance config (created on demand).
|
|
410
|
-
* For UI reactivity to connection changes, `onWalletConnectionChange` or derived hooks are preferred.
|
|
411
|
-
* @returns The current account status from Wagmi.
|
|
412
|
-
*/
|
|
413
|
-
public getWalletConnectionStatus(): GetAccountReturnType {
|
|
414
|
-
logger.debug(LOG_SYSTEM, 'getWalletConnectionStatus called.');
|
|
415
|
-
const configToUse =
|
|
416
|
-
this.activeWagmiConfig ||
|
|
417
|
-
this.defaultInstanceConfig ||
|
|
418
|
-
(this.defaultInstanceConfig = this.createDefaultConfig());
|
|
419
|
-
if (!configToUse) {
|
|
420
|
-
logger.error(LOG_SYSTEM, 'No config available for getWalletConnectionStatus!');
|
|
421
|
-
// Return a valid GetAccountReturnType for a disconnected state
|
|
422
|
-
return {
|
|
423
|
-
isConnected: false,
|
|
424
|
-
isConnecting: false,
|
|
425
|
-
isDisconnected: true,
|
|
426
|
-
isReconnecting: false,
|
|
427
|
-
status: 'disconnected',
|
|
428
|
-
address: undefined,
|
|
429
|
-
addresses: undefined,
|
|
430
|
-
chainId: undefined,
|
|
431
|
-
chain: undefined,
|
|
432
|
-
connector: undefined,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
return getAccount(configToUse);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Subscribes to account and connection status changes from Wagmi.
|
|
440
|
-
* The subscription is bound to the `activeWagmiConfig` if available at the time of call,
|
|
441
|
-
* otherwise to the default instance config. If `activeWagmiConfig` changes later,
|
|
442
|
-
* this specific subscription might become stale (see warning in `setActiveWagmiConfig`).
|
|
443
|
-
* @param callback - Function to call when connection status changes.
|
|
444
|
-
* @returns A function to unsubscribe from the changes.
|
|
445
|
-
*/
|
|
446
|
-
public onWalletConnectionChange(
|
|
447
|
-
callback: (status: GetAccountReturnType, prevStatus: GetAccountReturnType) => void
|
|
448
|
-
): () => void {
|
|
449
|
-
if (!this.initialized) {
|
|
450
|
-
logger.warn(LOG_SYSTEM, 'onWalletConnectionChange called before initialization. No-op.');
|
|
451
|
-
return () => {};
|
|
452
|
-
}
|
|
453
|
-
if (this.unsubscribe) {
|
|
454
|
-
this.unsubscribe();
|
|
455
|
-
logger.debug(LOG_SYSTEM, 'Previous watchAccount unsubscribed.');
|
|
456
|
-
}
|
|
457
|
-
const configToUse =
|
|
458
|
-
this.activeWagmiConfig ||
|
|
459
|
-
this.defaultInstanceConfig ||
|
|
460
|
-
(this.defaultInstanceConfig = this.createDefaultConfig());
|
|
461
|
-
if (!configToUse) {
|
|
462
|
-
logger.error(
|
|
463
|
-
LOG_SYSTEM,
|
|
464
|
-
'No config available for onWalletConnectionChange! Subscription not set.'
|
|
40
|
+
export function createEvmWalletImplementation(
|
|
41
|
+
walletConnectProjectId?: string,
|
|
42
|
+
initialUiKitConfig?: UiKitConfiguration
|
|
43
|
+
): CoreWagmiWalletImplementation {
|
|
44
|
+
const config: WagmiWalletConfig = {
|
|
45
|
+
chains: defaultSupportedChains,
|
|
46
|
+
networkConfigs: evmNetworks,
|
|
47
|
+
walletConnectProjectId,
|
|
48
|
+
initialUiKitConfig,
|
|
49
|
+
logSystem: 'WagmiWalletImplementation',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const instance = new CoreWagmiWalletImplementation(config);
|
|
53
|
+
|
|
54
|
+
// Inject the RainbowKit config function
|
|
55
|
+
instance.setRainbowKitConfigFn(
|
|
56
|
+
async (uiKitConfiguration, chains, chainIdToNetworkIdMap, getRpcOverride) => {
|
|
57
|
+
return getWagmiConfigForRainbowKit(
|
|
58
|
+
uiKitConfiguration,
|
|
59
|
+
chains as WagmiConfigChains,
|
|
60
|
+
chainIdToNetworkIdMap,
|
|
61
|
+
getRpcOverride
|
|
465
62
|
);
|
|
466
|
-
return () => {};
|
|
467
63
|
}
|
|
468
|
-
|
|
469
|
-
logger.info(
|
|
470
|
-
LOG_SYSTEM,
|
|
471
|
-
'watchAccount subscription established/re-established using config:',
|
|
472
|
-
configToUse === this.activeWagmiConfig ? 'activeExternal' : 'defaultInstance'
|
|
473
|
-
);
|
|
474
|
-
return this.unsubscribe;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// Methods that perform actions should use the most current activeWagmiConfig
|
|
478
|
-
/**
|
|
479
|
-
* Gets the Viem Wallet Client for the currently connected account and chain, using the active Wagmi config.
|
|
480
|
-
* @returns A Promise resolving to the Viem WalletClient or null if not connected or config not active.
|
|
481
|
-
*/
|
|
482
|
-
public async getWalletClient(): Promise<WalletClient | null> {
|
|
483
|
-
if (!this.initialized || !this.activeWagmiConfig) {
|
|
484
|
-
logger.warn(
|
|
485
|
-
LOG_SYSTEM,
|
|
486
|
-
'getWalletClient: Not initialized or no activeWagmiConfig. Returning null.'
|
|
487
|
-
);
|
|
488
|
-
return null;
|
|
489
|
-
}
|
|
490
|
-
const accountStatus = getAccount(this.activeWagmiConfig);
|
|
491
|
-
if (!accountStatus.isConnected || !accountStatus.chainId || !accountStatus.address) return null;
|
|
492
|
-
return getWagmiWalletClient(this.activeWagmiConfig, {
|
|
493
|
-
chainId: accountStatus.chainId,
|
|
494
|
-
account: accountStatus.address,
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
* Gets the Viem Public Client for the currently connected chain, using the active Wagmi config.
|
|
500
|
-
* Note: Direct public client retrieval from WagmiConfig is complex in v2. This is a placeholder.
|
|
501
|
-
* Prefer using Wagmi actions like readContract, simulateContract which use the public client internally.
|
|
502
|
-
* @returns A Promise resolving to the Viem PublicClient or null.
|
|
503
|
-
*/
|
|
504
|
-
public async getPublicClient(): Promise<PublicClient | null> {
|
|
505
|
-
if (!this.initialized || !this.activeWagmiConfig) {
|
|
506
|
-
logger.warn(
|
|
507
|
-
LOG_SYSTEM,
|
|
508
|
-
'getPublicClient: Not initialized or no activeWagmiConfig. Returning null.'
|
|
509
|
-
);
|
|
510
|
-
return null;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
const accountStatus = getAccount(this.activeWagmiConfig); // Get current chain from the active config
|
|
514
|
-
const currentChainId = accountStatus.chainId;
|
|
515
|
-
|
|
516
|
-
if (!currentChainId) {
|
|
517
|
-
logger.warn(
|
|
518
|
-
LOG_SYSTEM,
|
|
519
|
-
'getPublicClient: No connected chainId available from accountStatus. Returning null.'
|
|
520
|
-
);
|
|
521
|
-
return null;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
try {
|
|
525
|
-
// Use the getPublicClient action from wagmi/core
|
|
526
|
-
// It requires the config and optionally a chainId. If no chainId, it uses the config's primary/first chain.
|
|
527
|
-
// It's better to be explicit with the current chainId.
|
|
528
|
-
const publicClient = getWagmiCorePublicClient(this.activeWagmiConfig, {
|
|
529
|
-
chainId: currentChainId,
|
|
530
|
-
});
|
|
531
|
-
if (publicClient) {
|
|
532
|
-
logger.info(
|
|
533
|
-
LOG_SYSTEM,
|
|
534
|
-
`getPublicClient: Successfully retrieved public client for chainId ${currentChainId}.`
|
|
535
|
-
);
|
|
536
|
-
return publicClient;
|
|
537
|
-
}
|
|
538
|
-
logger.warn(
|
|
539
|
-
LOG_SYSTEM,
|
|
540
|
-
`getPublicClient: getWagmiCorePublicClient returned undefined/null for chainId ${currentChainId}.`
|
|
541
|
-
);
|
|
542
|
-
return null;
|
|
543
|
-
} catch (error) {
|
|
544
|
-
logger.error(LOG_SYSTEM, 'Error getting public client from wagmi/core:', error);
|
|
545
|
-
return null;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* Gets the list of available wallet connectors from the active Wagmi config.
|
|
551
|
-
* @returns A Promise resolving to an array of available connectors.
|
|
552
|
-
*/
|
|
553
|
-
public async getAvailableConnectors(): Promise<Connector[]> {
|
|
554
|
-
if (!this.initialized || !this.activeWagmiConfig) return [];
|
|
555
|
-
return this.activeWagmiConfig.connectors.map((co) => ({ id: co.uid, name: co.name }));
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
/**
|
|
559
|
-
* Initiates the connection process for a specific connector using the active Wagmi config.
|
|
560
|
-
* @param connectorId - The ID of the connector to use.
|
|
561
|
-
* @returns A Promise with connection result including address and chainId if successful.
|
|
562
|
-
*/
|
|
563
|
-
public async connect(
|
|
564
|
-
connectorId: string
|
|
565
|
-
): Promise<{ connected: boolean; address?: string; chainId?: number; error?: string }> {
|
|
566
|
-
if (!this.initialized || !this.activeWagmiConfig)
|
|
567
|
-
throw new Error('Wallet not initialized or no active config');
|
|
568
|
-
const connectorToUse = this.activeWagmiConfig.connectors.find(
|
|
569
|
-
(cn) => cn.id === connectorId || cn.uid === connectorId
|
|
570
|
-
);
|
|
571
|
-
if (!connectorToUse) throw new Error(`Connector ${connectorId} not found`);
|
|
572
|
-
const res = await connect(this.activeWagmiConfig, { connector: connectorToUse });
|
|
573
|
-
return { connected: true, address: res.accounts[0], chainId: res.chainId };
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Disconnects the currently connected wallet using the active Wagmi config.
|
|
578
|
-
* @returns A Promise with disconnection result.
|
|
579
|
-
*/
|
|
580
|
-
public async disconnect(): Promise<{ disconnected: boolean; error?: string }> {
|
|
581
|
-
if (!this.initialized || !this.activeWagmiConfig)
|
|
582
|
-
return { disconnected: false, error: 'Wallet not initialized or no active config' };
|
|
583
|
-
await disconnect(this.activeWagmiConfig);
|
|
584
|
-
return { disconnected: true };
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Prompts the user to switch to the specified network using the active Wagmi config.
|
|
589
|
-
* @param chainId - The target chain ID to switch to.
|
|
590
|
-
* @returns A Promise that resolves if the switch is successful, or rejects with an error.
|
|
591
|
-
*/
|
|
592
|
-
public async switchNetwork(chainId: number): Promise<void> {
|
|
593
|
-
if (!this.initialized || !this.activeWagmiConfig)
|
|
594
|
-
throw new Error('Wallet not initialized or no active config');
|
|
595
|
-
await switchChain(this.activeWagmiConfig, { chainId });
|
|
596
|
-
}
|
|
64
|
+
);
|
|
597
65
|
|
|
598
|
-
|
|
66
|
+
return instance;
|
|
599
67
|
}
|
package/src/wallet/index.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// Barrel file for wallet module
|
|
2
|
-
export
|
|
3
|
-
export * from './context';
|
|
2
|
+
export { EvmWalletUiRoot } from './components/EvmWalletUiRoot';
|
|
4
3
|
export * from './hooks';
|
|
5
4
|
export * from './types';
|
|
6
5
|
export * from './utils/index';
|
|
7
6
|
// Export specific functions from utils.ts to avoid conflicts
|
|
8
|
-
export { getResolvedWalletComponents
|
|
7
|
+
export { getResolvedWalletComponents } from './utils';
|
|
9
8
|
// Keep wagmi-implementation internal
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
|
+
import { generateRainbowKitExportables } from '@openzeppelin/ui-builder-adapter-evm-core';
|
|
3
4
|
import type { UiKitConfiguration } from '@openzeppelin/ui-types';
|
|
4
5
|
|
|
5
|
-
import { generateRainbowKitExportables } from '../export-service';
|
|
6
|
-
|
|
7
6
|
describe('RainbowKit Export Service', () => {
|
|
8
7
|
describe('generateRainbowKitExportables', () => {
|
|
9
8
|
it('should generate a valid RainbowKit config file with all properties', () => {
|