@dynamic-labs/ethereum 4.0.0-alpha.3 → 4.0.0-alpha.31

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/package.cjs +8 -0
  3. package/package.js +4 -0
  4. package/package.json +12 -17
  5. package/src/coinbase/coinbase.cjs +1 -3
  6. package/src/coinbase/coinbase.d.ts +2 -5
  7. package/src/coinbase/coinbase.js +2 -4
  8. package/src/coinbase/types.d.ts +2 -2
  9. package/src/ethProviderHelper.cjs +47 -38
  10. package/src/ethProviderHelper.d.ts +6 -6
  11. package/src/ethProviderHelper.js +48 -39
  12. package/src/index.cjs +11 -0
  13. package/src/index.d.ts +1 -1
  14. package/src/index.js +7 -1
  15. package/src/injected/ExodusEvm.cjs +1 -1
  16. package/src/injected/ExodusEvm.d.ts +3 -3
  17. package/src/injected/ExodusEvm.js +1 -1
  18. package/src/injected/FallbackEvmConnector.cjs +1 -1
  19. package/src/injected/FallbackEvmConnector.d.ts +3 -3
  20. package/src/injected/FallbackEvmConnector.js +1 -1
  21. package/src/injected/InjectedWalletBase.cjs +12 -6
  22. package/src/injected/InjectedWalletBase.d.ts +4 -6
  23. package/src/injected/InjectedWalletBase.js +11 -7
  24. package/src/injected/PhantomEvm.cjs +1 -1
  25. package/src/injected/PhantomEvm.d.ts +3 -3
  26. package/src/injected/PhantomEvm.js +1 -1
  27. package/src/injected/UnknownInjected.cjs +1 -1
  28. package/src/injected/UnknownInjected.d.ts +3 -3
  29. package/src/injected/UnknownInjected.js +1 -1
  30. package/src/injected/fetchInjectedWalletConnectors.cjs +4 -2
  31. package/src/injected/fetchInjectedWalletConnectors.js +4 -2
  32. package/src/injected/index.d.ts +1 -0
  33. package/src/metaMask/MetaMaskConnector.cjs +399 -0
  34. package/src/metaMask/MetaMaskConnector.d.ts +58 -0
  35. package/src/metaMask/MetaMaskConnector.js +395 -0
  36. package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.cjs +58 -0
  37. package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.d.ts +14 -0
  38. package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.js +54 -0
  39. package/src/metaMask/utils/isPendingWalletRequestPermissionError.cjs +11 -0
  40. package/src/metaMask/utils/isPendingWalletRequestPermissionError.d.ts +1 -0
  41. package/src/metaMask/utils/isPendingWalletRequestPermissionError.js +7 -0
  42. package/src/metaMask/utils/waitForConnection.cjs +10 -0
  43. package/src/metaMask/utils/waitForConnection.d.ts +2 -0
  44. package/src/metaMask/utils/waitForConnection.js +6 -0
  45. package/src/types.d.ts +1 -3
  46. package/src/utils/logger.cjs +10 -0
  47. package/src/utils/logger.d.ts +2 -0
  48. package/src/utils/logger.js +6 -0
  49. package/src/walletConnect/walletConnect.cjs +1 -3
  50. package/src/walletConnect/walletConnect.d.ts +4 -6
  51. package/src/walletConnect/walletConnect.js +2 -4
@@ -0,0 +1,395 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../_virtual/_tslib.js';
3
+ import { MetaMaskSDK } from '@metamask/sdk';
4
+ import { createWalletClient, custom, isHex, toHex } from 'viem';
5
+ import { EthereumWalletConnector, getOrMapViemChain } from '@dynamic-labs/ethereum-core';
6
+ import { eventListenerHandlers } from '@dynamic-labs/wallet-connector-core';
7
+ import { createEventTimeline, PlatformService, isMobile, retryableFn } from '@dynamic-labs/utils';
8
+ import { getWalletBookWallet, findWalletBookWallet } from '@dynamic-labs/wallet-book';
9
+ import { logger } from '../utils/logger.js';
10
+ import { EthProviderHelper } from '../ethProviderHelper.js';
11
+ import { createMetaMaskSDKDisplayUriState } from './utils/createMetaMaskSDKDisplayUriState.js';
12
+ import { waitForConnection } from './utils/waitForConnection.js';
13
+ import { isPendingWalletRequestPermissionError } from './utils/isPendingWalletRequestPermissionError.js';
14
+
15
+ /**
16
+ * The MetaMask SDK must be initialized only once, so we store the instance
17
+ * in these variables to avoid initializing it multiple times
18
+ */
19
+ let _metaMaskSDK = null;
20
+ let _metaMaskSDKDisplayUriState = null;
21
+ const eventTimeline = createEventTimeline();
22
+ class MetaMaskConnector extends EthereumWalletConnector {
23
+ constructor(props) {
24
+ super(props);
25
+ this.name = 'MetaMask';
26
+ this.overrideKey = 'metamask';
27
+ this.canConnectViaQrCode = true;
28
+ this.isInAppBrowser = false;
29
+ this.appName = props.appName;
30
+ this.appLogoUrl = props.appLogoUrl;
31
+ /**
32
+ * The isInAppBrowser must be calculated before initializing the MetaMask SDK.
33
+ *
34
+ * The isInAppBrowser is calculated by checking if the window provider is installed
35
+ * in the browser and if it is running on a mobile device.
36
+ *
37
+ * But the MetaMask SDK will inject its own provider to the window if not provider is injected.
38
+ * This means the MetaMask SDK can interfere with the isInAppBrowser calculation.
39
+ *
40
+ * So we need to calculate the isInAppBrowser before initializing the MetaMask SDK
41
+ * to prevent a false negative
42
+ */
43
+ this.isInAppBrowser = this.getIsInAppBrowser();
44
+ if (!_metaMaskSDK) {
45
+ this.createMetaMaskSDK();
46
+ }
47
+ }
48
+ getSupportedNetworks() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ return this.evmNetworks.map((network) => network.chainId.toString());
51
+ });
52
+ }
53
+ get ethProviderHelper() {
54
+ return new EthProviderHelper(getWalletBookWallet(this.walletBook, this.key));
55
+ }
56
+ get metaMaskSDK() {
57
+ if (!_metaMaskSDK)
58
+ throw new Error('MetaMaskSDK not initialized');
59
+ return _metaMaskSDK;
60
+ }
61
+ set metaMaskSDK(metaMaskSDK) {
62
+ _metaMaskSDK = metaMaskSDK;
63
+ }
64
+ get metaMaskSDKDisplayUriState() {
65
+ if (!_metaMaskSDKDisplayUriState)
66
+ throw new Error('MetaMaskSDKDisplayUriState not initialized');
67
+ return _metaMaskSDKDisplayUriState;
68
+ }
69
+ createMetaMaskSDK() {
70
+ const dappMetadata = {
71
+ iconUrl: this.appLogoUrl,
72
+ name: this.appName,
73
+ url: PlatformService.getOrigin(),
74
+ };
75
+ _metaMaskSDK = new MetaMaskSDK({
76
+ _source: 'dynamic-labs',
77
+ checkInstallationImmediately: true,
78
+ dappMetadata,
79
+ enableAnalytics: true,
80
+ extensionOnly: this.isInstalledOnBrowser(),
81
+ headless: true,
82
+ openDeeplink: PlatformService.openURL,
83
+ preferDesktop: !isMobile(),
84
+ readonlyRPCMap: getReadonlyRPCMap(this.evmNetworkRpcMap()),
85
+ useDeeplink: true,
86
+ });
87
+ _metaMaskSDKDisplayUriState =
88
+ createMetaMaskSDKDisplayUriState(_metaMaskSDK);
89
+ }
90
+ endSession() {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ eventTimeline.postEvent('disconnect');
93
+ /**
94
+ * The MetaMask SDK must be terminated and reinitialized on mobile
95
+ * to prevent deeplinks not working
96
+ */
97
+ if (isMobile()) {
98
+ return this.metaMaskSDK.terminate().then(() => {
99
+ _metaMaskSDK = null;
100
+ _metaMaskSDKDisplayUriState = null;
101
+ return this.createMetaMaskSDK();
102
+ });
103
+ }
104
+ /**
105
+ * Just terminate the SDK on desktop
106
+ */
107
+ return this.metaMaskSDK.terminate();
108
+ });
109
+ }
110
+ getAddress(opts) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ return new Promise((resolve, reject) => {
113
+ var _a, _b, _c, _d;
114
+ // QR Code flow
115
+ if (!isMobile() && Boolean(opts === null || opts === void 0 ? void 0 : opts.onDisplayUri)) {
116
+ this.metaMaskSDKDisplayUriState
117
+ .consumeDisplayUri()
118
+ .then((displayUri) => {
119
+ var _a;
120
+ if (!displayUri) {
121
+ reject(new Error('MetaMask display uri not found'));
122
+ return;
123
+ }
124
+ (_a = opts === null || opts === void 0 ? void 0 : opts.onDisplayUri) === null || _a === void 0 ? void 0 : _a.call(opts, displayUri);
125
+ });
126
+ }
127
+ // Deep link to MetaMask app in-app browser
128
+ if (this.shouldDeepLinkToMetaMaskInAppBrowser() &&
129
+ ((_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.mobile) === null || _b === void 0 ? void 0 : _b.inAppBrowser)) {
130
+ // Redirect to the in-app browser and append the current url
131
+ window.location.href = `${(_d = (_c = this.wallet) === null || _c === void 0 ? void 0 : _c.mobile) === null || _d === void 0 ? void 0 : _d.inAppBrowser}/${window.location.href}`;
132
+ resolve(undefined);
133
+ return;
134
+ }
135
+ // Connect to MetaMask
136
+ this.getConnectedAccountsSafely().then((initialConnectedAccounts) => __awaiter(this, void 0, void 0, function* () {
137
+ if (initialConnectedAccounts.length) {
138
+ resolve(initialConnectedAccounts[0]);
139
+ return;
140
+ }
141
+ try {
142
+ yield this.metaMaskSDK.connect();
143
+ }
144
+ catch (error) {
145
+ const isRequestPendingError = isPendingWalletRequestPermissionError(error);
146
+ if (!isRequestPendingError) {
147
+ throw error;
148
+ }
149
+ else {
150
+ yield waitForConnection(this.getProvider());
151
+ }
152
+ }
153
+ const accounts = yield this.getConnectedAccounts();
154
+ resolve(accounts[0]);
155
+ }));
156
+ });
157
+ });
158
+ }
159
+ getConnectedAccountsSafely() {
160
+ return __awaiter(this, void 0, void 0, function* () {
161
+ try {
162
+ const connectedAccounts = yield this.getConnectedAccounts();
163
+ return connectedAccounts;
164
+ }
165
+ catch (err) {
166
+ logger.error(err);
167
+ return [];
168
+ }
169
+ });
170
+ }
171
+ getConnectedAccounts() {
172
+ return __awaiter(this, void 0, void 0, function* () {
173
+ // Wait for for MetaMask SDK to initialize
174
+ yield this.metaMaskSDK.sdkInitPromise;
175
+ const provider = this.getProvider();
176
+ if (!provider) {
177
+ return [];
178
+ }
179
+ /**
180
+ * The eth_accounts method can hang on mobile devices when
181
+ * the MetaMask SDK has not connected yet. So we use a retryable
182
+ * to ensure the timeout will be respected
183
+ */
184
+ const accounts = yield retryableFn(() => provider.request({
185
+ method: 'eth_accounts',
186
+ params: [],
187
+ }), {
188
+ fallbackValue: [],
189
+ timeoutMs: 1000,
190
+ });
191
+ if (!(accounts === null || accounts === void 0 ? void 0 : accounts.length)) {
192
+ return [];
193
+ }
194
+ return accounts;
195
+ });
196
+ }
197
+ signMessage(messageToSign, withAddress) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ yield this.metaMaskSDK.sdkInitPromise;
200
+ /**
201
+ * Should wait for the window to be focused on mobile
202
+ * to account for the user moving between the MetaMaskApp
203
+ * and the browser
204
+ */
205
+ const windowFocusPromiseForMobile = !this.isInAppBrowser && isMobile()
206
+ ? waitForFocusWindowEvent()
207
+ : Promise.resolve();
208
+ const provider = this.getProvider();
209
+ if (!provider) {
210
+ return undefined;
211
+ }
212
+ const [selectedAddress] = yield this.getConnectedAccounts();
213
+ const effectiveAddress = withAddress !== null && withAddress !== void 0 ? withAddress : selectedAddress;
214
+ if (!effectiveAddress) {
215
+ return undefined;
216
+ }
217
+ const walletClient = this.getWalletClientForAddress(effectiveAddress);
218
+ if (!walletClient)
219
+ return undefined;
220
+ const signature = yield walletClient.signMessage({
221
+ message: messageToSign,
222
+ });
223
+ yield windowFocusPromiseForMobile;
224
+ return signature;
225
+ });
226
+ }
227
+ chooseAccountsToConnect() {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ return [];
230
+ });
231
+ }
232
+ getWalletClient(chainId) {
233
+ const provider = this.getProvider();
234
+ if (!provider) {
235
+ return undefined;
236
+ }
237
+ const selectedAddress = provider.getSelectedAddress();
238
+ return this.getWalletClientForAddress(selectedAddress || undefined, chainId);
239
+ }
240
+ get rdns() {
241
+ const { rdns } = this.metadata;
242
+ if (!rdns) {
243
+ throw new Error('rdns not found in metadata');
244
+ }
245
+ return rdns;
246
+ }
247
+ isInstalledOnBrowser() {
248
+ var _a;
249
+ const metaMaskEip6963Provider = (_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns);
250
+ const isInstalled = Boolean(metaMaskEip6963Provider);
251
+ return isInstalled;
252
+ }
253
+ setupEventListeners() {
254
+ return __awaiter(this, void 0, void 0, function* () {
255
+ yield this.metaMaskSDK.sdkInitPromise;
256
+ const metaMaskProvider = this.getProvider();
257
+ if (!metaMaskProvider) {
258
+ return;
259
+ }
260
+ const { handleAccountChange, handleChainChange, handleDisconnect } = eventListenerHandlers(this);
261
+ const handleAccountsChangedFromMetaMask = (accounts) => {
262
+ /**
263
+ * MetaMask emits an account changed event when the wallet is disconnected
264
+ * so we ignore the accountsChanged event if the disconnect event was recent
265
+ */
266
+ if (eventTimeline.isEventRecent('disconnect', 1000)) {
267
+ return;
268
+ }
269
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
270
+ // @ts-ignore
271
+ handleAccountChange(accounts);
272
+ };
273
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
274
+ // @ts-ignore
275
+ metaMaskProvider.on('accountsChanged', handleAccountsChangedFromMetaMask);
276
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
277
+ // @ts-ignore
278
+ metaMaskProvider.on('chainChanged', handleChainChange);
279
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
280
+ // @ts-ignore
281
+ metaMaskProvider.on('disconnect', handleDisconnect);
282
+ this.teardownEventListeners = () => {
283
+ metaMaskProvider.off('accountsChanged', handleAccountsChangedFromMetaMask);
284
+ metaMaskProvider.off('chainChanged', handleChainChange);
285
+ metaMaskProvider.off('disconnect', handleDisconnect);
286
+ };
287
+ });
288
+ }
289
+ /**
290
+ * This override is necessary to wait for the MetaMask SDK to initialize
291
+ * before calling the super method. Otherwise, the super method may fail
292
+ * to fetch the provider
293
+ */
294
+ getNetwork() {
295
+ const _super = Object.create(null, {
296
+ getNetwork: { get: () => super.getNetwork }
297
+ });
298
+ return __awaiter(this, void 0, void 0, function* () {
299
+ yield this.metaMaskSDK.sdkInitPromise;
300
+ const net = yield _super.getNetwork.call(this);
301
+ return net;
302
+ });
303
+ }
304
+ // Utils
305
+ getProvider() {
306
+ var _a;
307
+ return ((_a = this.metaMaskSDK.getProvider()) !== null && _a !== void 0 ? _a : this.metaMaskSDK.getMobileProvider());
308
+ }
309
+ evmNetworkByChainId(chainId) {
310
+ return this.evmNetworks.find((network) => network.chainId === chainId);
311
+ }
312
+ getWalletClientForAddress(address, chainId) {
313
+ var _a, _b;
314
+ const provider = this.getProvider();
315
+ if (!provider) {
316
+ return undefined;
317
+ }
318
+ const effectiveChainId = (_b = (_a = this.toInt(chainId)) !== null && _a !== void 0 ? _a : this.getCurrentChainId()) !== null && _b !== void 0 ? _b : '1';
319
+ const network = this.evmNetworkByChainId(effectiveChainId);
320
+ return createWalletClient({
321
+ account: address,
322
+ chain: network ? getOrMapViemChain(network) : this.getActiveChain(),
323
+ transport: custom(provider),
324
+ });
325
+ }
326
+ toInt(chainId) {
327
+ if (!chainId)
328
+ return undefined;
329
+ try {
330
+ return parseInt(chainId);
331
+ }
332
+ catch (err) {
333
+ logger.debug(err);
334
+ return undefined;
335
+ }
336
+ }
337
+ getCurrentChainId() {
338
+ const provider = this.getProvider();
339
+ if (!provider) {
340
+ return undefined;
341
+ }
342
+ const chainId = provider.getChainId();
343
+ if (isHex(chainId)) {
344
+ return parseInt(chainId);
345
+ }
346
+ return chainId;
347
+ }
348
+ /**
349
+ * Checks if the current environment is the MetaMask in-app browser
350
+ * by checking if the MetaMask provider is installed in the window object
351
+ * on a mobile device
352
+ */
353
+ getIsInAppBrowser() {
354
+ var _a, _b;
355
+ if (!isMobile())
356
+ return false;
357
+ const provider = ((_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns)) ||
358
+ ((_b = this.ethProviderHelper) === null || _b === void 0 ? void 0 : _b.getInjectedProvider());
359
+ return Boolean(provider);
360
+ }
361
+ shouldDeepLinkToMetaMaskInAppBrowser() {
362
+ var _a;
363
+ // Not in an in-app browser
364
+ if (this.isInAppBrowser)
365
+ return false;
366
+ // Not a mobile device
367
+ if (!isMobile())
368
+ return false;
369
+ // SDK is configured to use the in-app browser
370
+ if (this.mobileExperience !== 'in-app-browser')
371
+ return false;
372
+ const isAppBrowserLinkPresent = ((_a = this.wallet) === null || _a === void 0 ? void 0 : _a.mobile) && this.wallet.mobile.inAppBrowser;
373
+ // Wallet has an in-app browser link
374
+ if (!isAppBrowserLinkPresent)
375
+ return false;
376
+ return true;
377
+ }
378
+ /**
379
+ * Get wallet book wallet information
380
+ */
381
+ get wallet() {
382
+ return findWalletBookWallet(this.walletBook, this.key);
383
+ }
384
+ }
385
+ // Utils
386
+ const getReadonlyRPCMap = (evmNetworkRpcMap) => Object.keys(evmNetworkRpcMap).reduce((acc, chainId) => (Object.assign(Object.assign({}, acc), { [toHex(parseInt(chainId))]: evmNetworkRpcMap[chainId] })), {});
387
+ /**
388
+ * Waits for the focus page event and await for an extra second
389
+ * This is necessary to ensure the verify call will succeed
390
+ */
391
+ const waitForFocusWindowEvent = () => new Promise((resolve) => {
392
+ window.addEventListener('focus', resolve);
393
+ }).then(() => new Promise((resolve) => setTimeout(resolve, 1000)));
394
+
395
+ export { MetaMaskConnector };
@@ -0,0 +1,58 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../_virtual/_tslib.cjs');
7
+
8
+ /**
9
+ * Listens for the `display_uri` event emitted by the MetaMask SDK.
10
+ *
11
+ * The `display_uri` event is triggered during SDK initialization or when the `connect` method is called.
12
+ * Calling `terminate` in the MetaMask SDK resets the connection, and a new `display_uri` will only be emitted
13
+ * when `connect` is called again.
14
+ *
15
+ * This function manages the new `display_uri` received from these events.
16
+ */
17
+ const createMetaMaskSDKDisplayUriState = (metaMaskSDK) => {
18
+ let lastKnownMetaMaskDeepLinkUri = null;
19
+ let displayUri = null;
20
+ metaMaskSDK.on('display_uri', (latestDisplayUri) => {
21
+ if (lastKnownMetaMaskDeepLinkUri !== latestDisplayUri) {
22
+ lastKnownMetaMaskDeepLinkUri = latestDisplayUri;
23
+ displayUri = latestDisplayUri.trim();
24
+ }
25
+ });
26
+ return {
27
+ consumeDisplayUri: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
28
+ const currentDisplayUri = displayUri;
29
+ if (currentDisplayUri) {
30
+ displayUri = null;
31
+ return currentDisplayUri;
32
+ }
33
+ return new Promise((resolve) => {
34
+ let timeoutId = null;
35
+ let intervalId = null;
36
+ const cleanUp = () => {
37
+ if (timeoutId)
38
+ clearTimeout(timeoutId);
39
+ if (intervalId)
40
+ clearInterval(intervalId);
41
+ };
42
+ timeoutId = setTimeout(() => {
43
+ cleanUp();
44
+ resolve(undefined);
45
+ }, 1000);
46
+ intervalId = setInterval(() => {
47
+ if (displayUri) {
48
+ cleanUp();
49
+ resolve(displayUri);
50
+ displayUri = null;
51
+ }
52
+ }, 10);
53
+ });
54
+ }),
55
+ };
56
+ };
57
+
58
+ exports.createMetaMaskSDKDisplayUriState = createMetaMaskSDKDisplayUriState;
@@ -0,0 +1,14 @@
1
+ import { MetaMaskSDK } from '@metamask/sdk';
2
+ export type MetaMaskSDKDisplayUriState = {
3
+ consumeDisplayUri: () => Promise<string | undefined>;
4
+ };
5
+ /**
6
+ * Listens for the `display_uri` event emitted by the MetaMask SDK.
7
+ *
8
+ * The `display_uri` event is triggered during SDK initialization or when the `connect` method is called.
9
+ * Calling `terminate` in the MetaMask SDK resets the connection, and a new `display_uri` will only be emitted
10
+ * when `connect` is called again.
11
+ *
12
+ * This function manages the new `display_uri` received from these events.
13
+ */
14
+ export declare const createMetaMaskSDKDisplayUriState: (metaMaskSDK: MetaMaskSDK) => MetaMaskSDKDisplayUriState;
@@ -0,0 +1,54 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../_virtual/_tslib.js';
3
+
4
+ /**
5
+ * Listens for the `display_uri` event emitted by the MetaMask SDK.
6
+ *
7
+ * The `display_uri` event is triggered during SDK initialization or when the `connect` method is called.
8
+ * Calling `terminate` in the MetaMask SDK resets the connection, and a new `display_uri` will only be emitted
9
+ * when `connect` is called again.
10
+ *
11
+ * This function manages the new `display_uri` received from these events.
12
+ */
13
+ const createMetaMaskSDKDisplayUriState = (metaMaskSDK) => {
14
+ let lastKnownMetaMaskDeepLinkUri = null;
15
+ let displayUri = null;
16
+ metaMaskSDK.on('display_uri', (latestDisplayUri) => {
17
+ if (lastKnownMetaMaskDeepLinkUri !== latestDisplayUri) {
18
+ lastKnownMetaMaskDeepLinkUri = latestDisplayUri;
19
+ displayUri = latestDisplayUri.trim();
20
+ }
21
+ });
22
+ return {
23
+ consumeDisplayUri: () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const currentDisplayUri = displayUri;
25
+ if (currentDisplayUri) {
26
+ displayUri = null;
27
+ return currentDisplayUri;
28
+ }
29
+ return new Promise((resolve) => {
30
+ let timeoutId = null;
31
+ let intervalId = null;
32
+ const cleanUp = () => {
33
+ if (timeoutId)
34
+ clearTimeout(timeoutId);
35
+ if (intervalId)
36
+ clearInterval(intervalId);
37
+ };
38
+ timeoutId = setTimeout(() => {
39
+ cleanUp();
40
+ resolve(undefined);
41
+ }, 1000);
42
+ intervalId = setInterval(() => {
43
+ if (displayUri) {
44
+ cleanUp();
45
+ resolve(displayUri);
46
+ displayUri = null;
47
+ }
48
+ }, 10);
49
+ });
50
+ }),
51
+ };
52
+ };
53
+
54
+ export { createMetaMaskSDKDisplayUriState };
@@ -0,0 +1,11 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ const isPendingWalletRequestPermissionError = (error) => typeof error === 'object' &&
7
+ error !== null &&
8
+ 'message' in error &&
9
+ error.message.includes("Request of type 'wallet_requestPermissions' already pending for origin");
10
+
11
+ exports.isPendingWalletRequestPermissionError = isPendingWalletRequestPermissionError;
@@ -0,0 +1 @@
1
+ export declare const isPendingWalletRequestPermissionError: (error: any) => any;
@@ -0,0 +1,7 @@
1
+ 'use client'
2
+ const isPendingWalletRequestPermissionError = (error) => typeof error === 'object' &&
3
+ error !== null &&
4
+ 'message' in error &&
5
+ error.message.includes("Request of type 'wallet_requestPermissions' already pending for origin");
6
+
7
+ export { isPendingWalletRequestPermissionError };
@@ -0,0 +1,10 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ const waitForConnection = (provider) => new Promise((resolve) => {
7
+ provider.once('connect', () => resolve());
8
+ });
9
+
10
+ exports.waitForConnection = waitForConnection;
@@ -0,0 +1,2 @@
1
+ import { SDKProvider } from '@metamask/sdk';
2
+ export declare const waitForConnection: (provider: SDKProvider) => Promise<void>;
@@ -0,0 +1,6 @@
1
+ 'use client'
2
+ const waitForConnection = (provider) => new Promise((resolve) => {
3
+ provider.once('connect', () => resolve());
4
+ });
5
+
6
+ export { waitForConnection };
package/src/types.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { EventEmitter } from 'stream';
1
+ import { type EventEmitter } from 'eventemitter3';
4
2
  import { PublicClient } from 'viem';
5
3
  import { ProviderCondition } from '@dynamic-labs/wallet-connector-core';
6
4
  declare global {
@@ -0,0 +1,10 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var logger$1 = require('@dynamic-labs/logger');
7
+
8
+ const logger = new logger$1.Logger('@dynamic-labs/ethereum');
9
+
10
+ exports.logger = logger;
@@ -0,0 +1,2 @@
1
+ import { Logger } from '@dynamic-labs/logger';
2
+ export declare const logger: Logger;
@@ -0,0 +1,6 @@
1
+ 'use client'
2
+ import { Logger } from '@dynamic-labs/logger';
3
+
4
+ const logger = new Logger('@dynamic-labs/ethereum');
5
+
6
+ export { logger };
@@ -23,12 +23,10 @@ const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}
23
23
  const swicthedNetworkKey = (walletName) => `dynamic-wc2-switched-network-${walletName}`;
24
24
  const currentChainKey = (walletName) => `dynamic-wc2-current-chain-${walletName}`;
25
25
  const ee = new EventEmitter__default["default"]();
26
- class WalletConnect extends ethereumCore.EthWalletConnector {
26
+ class WalletConnect extends ethereumCore.EthereumWalletConnector {
27
27
  constructor(opts) {
28
28
  var _a;
29
29
  super(opts);
30
- this.supportedChains = ['EVM', 'ETH'];
31
- this.connectedChain = 'EVM';
32
30
  this.isInitialized = false;
33
31
  this.canConnectViaQrCode = true;
34
32
  this.isWalletConnect = true;
@@ -1,17 +1,15 @@
1
1
  import type { SessionTypes } from '@walletconnect/types';
2
2
  import { WalletClient, Account, Transport, Chain as ViemChain } from 'viem';
3
- import { Chain, GetAddressOpts, DeepLinkVariant, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
3
+ import { GetAddressOpts, DeepLinkVariant, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
4
4
  import { EvmNetwork } from '@dynamic-labs/types';
5
- import { EthWalletConnector, EthWalletConnectorOpts } from '@dynamic-labs/ethereum-core';
6
- export type WalletConnectOpts = EthWalletConnectorOpts & {
5
+ import { EthereumWalletConnector, EthereumWalletConnectorOpts } from '@dynamic-labs/ethereum-core';
6
+ export type WalletConnectOpts = EthereumWalletConnectorOpts & {
7
7
  projectId?: string;
8
8
  walletName: string;
9
9
  deepLinkPreference?: DeepLinkVariant;
10
10
  walletConnectPreferredChains?: `eip155:${number}`[];
11
11
  };
12
- export declare class WalletConnect extends EthWalletConnector implements IWalletConnectConnector {
13
- supportedChains: Chain[];
14
- connectedChain: Chain;
12
+ export declare class WalletConnect extends EthereumWalletConnector implements IWalletConnectConnector {
15
13
  name: string;
16
14
  session: SessionTypes.Struct | undefined;
17
15
  isInitialized: boolean;
@@ -6,7 +6,7 @@ import { createWalletClient, custom } from 'viem';
6
6
  import { logger, performPlatformSpecificConnectionMethod, getDeepLink } from '@dynamic-labs/wallet-connector-core';
7
7
  import { getWalletBookWallet } from '@dynamic-labs/wallet-book';
8
8
  import { DynamicError, sleep, isMobile } from '@dynamic-labs/utils';
9
- import { EthWalletConnector, chainsMap } from '@dynamic-labs/ethereum-core';
9
+ import { EthereumWalletConnector, chainsMap } from '@dynamic-labs/ethereum-core';
10
10
  import { parseIntSafe } from '../utils/parseIntSafe.js';
11
11
 
12
12
  const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
@@ -14,12 +14,10 @@ const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}
14
14
  const swicthedNetworkKey = (walletName) => `dynamic-wc2-switched-network-${walletName}`;
15
15
  const currentChainKey = (walletName) => `dynamic-wc2-current-chain-${walletName}`;
16
16
  const ee = new EventEmitter();
17
- class WalletConnect extends EthWalletConnector {
17
+ class WalletConnect extends EthereumWalletConnector {
18
18
  constructor(opts) {
19
19
  var _a;
20
20
  super(opts);
21
- this.supportedChains = ['EVM', 'ETH'];
22
- this.connectedChain = 'EVM';
23
21
  this.isInitialized = false;
24
22
  this.canConnectViaQrCode = true;
25
23
  this.isWalletConnect = true;