@dynamic-labs/ethereum 4.9.4 → 4.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +10 -10
- package/src/EthereumWalletConnectorsWithConfig.cjs +5 -1
- package/src/EthereumWalletConnectorsWithConfig.js +5 -1
- package/src/coinbase/coinbase.cjs +1 -1
- package/src/coinbase/coinbase.js +1 -1
- package/src/ethProviderHelper.cjs +1 -1
- package/src/ethProviderHelper.js +1 -1
- package/src/metaMask/MetaMaskConnector.cjs +58 -45
- package/src/metaMask/MetaMaskConnector.d.ts +2 -2
- package/src/metaMask/MetaMaskConnector.js +58 -47
- package/src/walletConnect/WalletConnectConnector/WalletConnectConnector.cjs +2 -1
- package/src/walletConnect/WalletConnectConnector/WalletConnectConnector.d.ts +1 -0
- package/src/walletConnect/WalletConnectConnector/WalletConnectConnector.js +2 -1
- package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.cjs +0 -59
- package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.d.ts +0 -15
- package/src/metaMask/utils/createMetaMaskSDKDisplayUriState.js +0 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.9.6](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.5...v4.9.6) (2025-03-21)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add initial sui support ([#8317](https://github.com/dynamic-labs/dynamic-auth/issues/8317)) ([88c0234](https://github.com/dynamic-labs/dynamic-auth/commit/88c023483bad5736f38cb313b035279460f6e256))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* allow metmask sdk to retry connection ([#8322](https://github.com/dynamic-labs/dynamic-auth/issues/8322)) ([603ed99](https://github.com/dynamic-labs/dynamic-auth/commit/603ed99de3b5d90ac4f5eabcdcd3b2e90863298f))
|
|
13
|
+
* css for profile page without embedded wallets ([#8339](https://github.com/dynamic-labs/dynamic-auth/issues/8339)) ([7f696e9](https://github.com/dynamic-labs/dynamic-auth/commit/7f696e9986ddd899d140640f9af7cfd2dcd7c37a))
|
|
14
|
+
* ensure metamask connector can get display uri for multiple connections ([#8324](https://github.com/dynamic-labs/dynamic-auth/issues/8324)) ([1d95f08](https://github.com/dynamic-labs/dynamic-auth/commit/1d95f089589779e8ef078b80bd84fa0754179696))
|
|
15
|
+
* pass HttpTransportConfig to WalletClient, not just PublicClient ([#8333](https://github.com/dynamic-labs/dynamic-auth/issues/8333)) ([a0ddd10](https://github.com/dynamic-labs/dynamic-auth/commit/a0ddd10f1df57555cf0a3ed777f5d354eb140582))
|
|
16
|
+
|
|
17
|
+
### [4.9.5](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.4...v4.9.5) (2025-03-19)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* add support for AA to Global Wallet ([#8294](https://github.com/dynamic-labs/dynamic-auth/issues/8294)) ([173dfb9](https://github.com/dynamic-labs/dynamic-auth/commit/173dfb9c00e4307feec6ab11913f1a80310885eb))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* Remove the usage of random uuid in Global Wallet ([#8314](https://github.com/dynamic-labs/dynamic-auth/issues/8314)) ([79a7a64](https://github.com/dynamic-labs/dynamic-auth/commit/79a7a640b9ce470051a3c877ea46e8d4c94ea542))
|
|
28
|
+
* Fix UI when token balance is 0 ([#8299](https://github.com/dynamic-labs/dynamic-auth/issues/8299)) ([e8a2eca](https://github.com/dynamic-labs/dynamic-auth/commit/e8a2eca9876d914db738557a74751537eee2e129))
|
|
29
|
+
|
|
2
30
|
### [4.9.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.3...v4.9.4) (2025-03-17)
|
|
3
31
|
|
|
4
32
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/ethereum",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.6",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
"eventemitter3": "5.0.1",
|
|
24
24
|
"buffer": "6.0.3",
|
|
25
25
|
"@metamask/sdk": "0.32.0",
|
|
26
|
-
"@dynamic-labs/assert-package-version": "4.9.
|
|
27
|
-
"@dynamic-labs/embedded-wallet-evm": "4.9.
|
|
28
|
-
"@dynamic-labs/ethereum-core": "4.9.
|
|
29
|
-
"@dynamic-labs/logger": "4.9.
|
|
30
|
-
"@dynamic-labs/rpc-providers": "4.9.
|
|
31
|
-
"@dynamic-labs/types": "4.9.
|
|
32
|
-
"@dynamic-labs/utils": "4.9.
|
|
33
|
-
"@dynamic-labs/wallet-book": "4.9.
|
|
34
|
-
"@dynamic-labs/wallet-connector-core": "4.9.
|
|
26
|
+
"@dynamic-labs/assert-package-version": "4.9.6",
|
|
27
|
+
"@dynamic-labs/embedded-wallet-evm": "4.9.6",
|
|
28
|
+
"@dynamic-labs/ethereum-core": "4.9.6",
|
|
29
|
+
"@dynamic-labs/logger": "4.9.6",
|
|
30
|
+
"@dynamic-labs/rpc-providers": "4.9.6",
|
|
31
|
+
"@dynamic-labs/types": "4.9.6",
|
|
32
|
+
"@dynamic-labs/utils": "4.9.6",
|
|
33
|
+
"@dynamic-labs/wallet-book": "4.9.6",
|
|
34
|
+
"@dynamic-labs/wallet-connector-core": "4.9.6"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"viem": "^2.21.55"
|
|
@@ -10,7 +10,11 @@ const EthereumWalletConnectorsWithConfig = (providersConfig) => {
|
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
11
|
constructor(...args) {
|
|
12
12
|
const [opts] = args;
|
|
13
|
-
|
|
13
|
+
// TODO: remove this once we remove the deprecated `publicClientHttpTransportConfig`
|
|
14
|
+
const updatedProviderConfig = {
|
|
15
|
+
httpTransportConfig: Object.assign(Object.assign({}, providersConfig.httpTransportConfig), providersConfig.publicClientHttpTransportConfig),
|
|
16
|
+
};
|
|
17
|
+
super(Object.assign(Object.assign({}, opts), { providersConfig: updatedProviderConfig }));
|
|
14
18
|
}
|
|
15
19
|
};
|
|
16
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -6,7 +6,11 @@ const EthereumWalletConnectorsWithConfig = (providersConfig) => {
|
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
7
|
constructor(...args) {
|
|
8
8
|
const [opts] = args;
|
|
9
|
-
|
|
9
|
+
// TODO: remove this once we remove the deprecated `publicClientHttpTransportConfig`
|
|
10
|
+
const updatedProviderConfig = {
|
|
11
|
+
httpTransportConfig: Object.assign(Object.assign({}, providersConfig.httpTransportConfig), providersConfig.publicClientHttpTransportConfig),
|
|
12
|
+
};
|
|
13
|
+
super(Object.assign(Object.assign({}, opts), { providersConfig: updatedProviderConfig }));
|
|
10
14
|
}
|
|
11
15
|
};
|
|
12
16
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -90,7 +90,7 @@ class Coinbase extends ethereumCore.EthereumWalletConnector {
|
|
|
90
90
|
return viem.createWalletClient({
|
|
91
91
|
account: this.getActiveAccount(),
|
|
92
92
|
chain: chainId ? ethereumCore.chainsMap[chainId] : this.getActiveChain(),
|
|
93
|
-
transport: viem.custom(this.coinbaseProvider),
|
|
93
|
+
transport: viem.custom(this.coinbaseProvider, this.providersConfig.httpTransportConfig),
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
}
|
package/src/coinbase/coinbase.js
CHANGED
|
@@ -86,7 +86,7 @@ class Coinbase extends EthereumWalletConnector {
|
|
|
86
86
|
return createWalletClient({
|
|
87
87
|
account: this.getActiveAccount(),
|
|
88
88
|
chain: chainId ? chainsMap[chainId] : this.getActiveChain(),
|
|
89
|
-
transport: custom(this.coinbaseProvider),
|
|
89
|
+
transport: custom(this.coinbaseProvider, this.providersConfig.httpTransportConfig),
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -90,7 +90,7 @@ class EthProviderHelper {
|
|
|
90
90
|
chain: chainId ? ethereumCore.chainsMap[chainId] : this.connector.getActiveChain(),
|
|
91
91
|
transport: viem.custom({
|
|
92
92
|
request: (args) => provider.request(args).catch(normalizeRpcError.normalizeRpcError),
|
|
93
|
-
}),
|
|
93
|
+
}, this.connector.providersConfig.httpTransportConfig),
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
getAddress() {
|
package/src/ethProviderHelper.js
CHANGED
|
@@ -86,7 +86,7 @@ class EthProviderHelper {
|
|
|
86
86
|
chain: chainId ? chainsMap[chainId] : this.connector.getActiveChain(),
|
|
87
87
|
transport: custom({
|
|
88
88
|
request: (args) => provider.request(args).catch(normalizeRpcError),
|
|
89
|
-
}),
|
|
89
|
+
}, this.connector.providersConfig.httpTransportConfig),
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
getAddress() {
|
|
@@ -11,7 +11,6 @@ var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
|
11
11
|
var utils = require('@dynamic-labs/utils');
|
|
12
12
|
var logger = require('../utils/logger.cjs');
|
|
13
13
|
var InjectedWalletBase = require('../injected/InjectedWalletBase.cjs');
|
|
14
|
-
var createMetaMaskSDKDisplayUriState = require('./utils/createMetaMaskSDKDisplayUriState.cjs');
|
|
15
14
|
var waitForConnection = require('./utils/waitForConnection.cjs');
|
|
16
15
|
var isPendingWalletRequestPermissionError = require('./utils/isPendingWalletRequestPermissionError.cjs');
|
|
17
16
|
|
|
@@ -20,8 +19,11 @@ var isPendingWalletRequestPermissionError = require('./utils/isPendingWalletRequ
|
|
|
20
19
|
* in these variables to avoid initializing it multiple times
|
|
21
20
|
*/
|
|
22
21
|
let _metaMaskSDK = null;
|
|
23
|
-
let
|
|
22
|
+
let _metaMaskDisplayUri = null;
|
|
24
23
|
const eventTimeline = utils.createEventTimeline();
|
|
24
|
+
const setMetaMaskDisplayUri = (displayUri) => {
|
|
25
|
+
_metaMaskDisplayUri = displayUri;
|
|
26
|
+
};
|
|
25
27
|
class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
26
28
|
constructor(props) {
|
|
27
29
|
super(props);
|
|
@@ -44,6 +46,11 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
44
46
|
* to prevent a false negative
|
|
45
47
|
*/
|
|
46
48
|
this.isInAppBrowser = this.getIsInAppBrowser();
|
|
49
|
+
/**
|
|
50
|
+
* We can handle multiple connections in MetaMask only when the provider
|
|
51
|
+
* is installed on the browser.
|
|
52
|
+
*/
|
|
53
|
+
this.canHandleMultipleConnections = this.isInstalledOnBrowser();
|
|
47
54
|
if (!_metaMaskSDK) {
|
|
48
55
|
this.createMetaMaskSDK();
|
|
49
56
|
}
|
|
@@ -67,11 +74,6 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
67
74
|
set metaMaskSDK(metaMaskSDK) {
|
|
68
75
|
_metaMaskSDK = metaMaskSDK;
|
|
69
76
|
}
|
|
70
|
-
get metaMaskSDKDisplayUriState() {
|
|
71
|
-
if (!_metaMaskSDKDisplayUriState)
|
|
72
|
-
throw new Error('MetaMaskSDKDisplayUriState not initialized');
|
|
73
|
-
return _metaMaskSDKDisplayUriState;
|
|
74
|
-
}
|
|
75
77
|
createMetaMaskSDK() {
|
|
76
78
|
const dappMetadata = {
|
|
77
79
|
iconUrl: this.appLogoUrl,
|
|
@@ -90,8 +92,6 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
90
92
|
readonlyRPCMap: getReadonlyRPCMap(this.evmNetworkRpcMap()),
|
|
91
93
|
useDeeplink: true,
|
|
92
94
|
});
|
|
93
|
-
_metaMaskSDKDisplayUriState =
|
|
94
|
-
createMetaMaskSDKDisplayUriState.createMetaMaskSDKDisplayUriState(_metaMaskSDK);
|
|
95
95
|
}
|
|
96
96
|
endSession() {
|
|
97
97
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -103,7 +103,6 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
103
103
|
if (utils.isMobile()) {
|
|
104
104
|
return this.metaMaskSDK.terminate().then(() => {
|
|
105
105
|
_metaMaskSDK = null;
|
|
106
|
-
_metaMaskSDKDisplayUriState = null;
|
|
107
106
|
return this.createMetaMaskSDK();
|
|
108
107
|
});
|
|
109
108
|
}
|
|
@@ -115,50 +114,62 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
115
114
|
}
|
|
116
115
|
getAddress(opts) {
|
|
117
116
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
117
|
+
yield this.metaMaskSDK.sdkInitPromise;
|
|
118
|
+
// QR Code flow
|
|
119
|
+
const handleDisplayUri = (displayUri) => {
|
|
120
|
+
var _a;
|
|
121
|
+
if (!displayUri)
|
|
122
|
+
return;
|
|
123
|
+
setMetaMaskDisplayUri(displayUri);
|
|
124
|
+
(_a = opts === null || opts === void 0 ? void 0 : opts.onDisplayUri) === null || _a === void 0 ? void 0 : _a.call(opts, displayUri);
|
|
125
|
+
};
|
|
126
|
+
if (!utils.isMobile() && Boolean(opts === null || opts === void 0 ? void 0 : opts.onDisplayUri)) {
|
|
127
|
+
this.metaMaskSDK.on('display_uri', handleDisplayUri);
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
132
130
|
// Deep link to MetaMask app in-app browser
|
|
133
131
|
if (this.shouldDeepLinkToMetaMaskInAppBrowser() &&
|
|
134
132
|
this.metadata.inAppBrowserUrl) {
|
|
135
133
|
// Redirect to the in-app browser and append the current url
|
|
136
134
|
utils.PlatformService.openURL(`${this.metadata.inAppBrowserUrl}/${window.location.href}`);
|
|
137
|
-
resolve(undefined);
|
|
138
135
|
return;
|
|
139
136
|
}
|
|
140
137
|
// Connect to MetaMask
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
const initialConnectedAccounts = yield this.getConnectedAccountsSafely();
|
|
139
|
+
if (initialConnectedAccounts.length) {
|
|
140
|
+
return this.parseAddress(initialConnectedAccounts[0]);
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
yield this.metaMaskSDK.connect();
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
/**
|
|
147
|
+
* In case of a getAddress call was already made and is pending
|
|
148
|
+
* and a new getAddress call is made after a endSession call, the
|
|
149
|
+
* MetaMask SDK will reject the original connect calls in the getAddress
|
|
150
|
+
* promise.
|
|
151
|
+
*
|
|
152
|
+
* In this case we want to cast the error to GetAddressCancelledError
|
|
153
|
+
* so the SDK knows the original getAddres call is cancelled and
|
|
154
|
+
* be clear to start the new getAddress flow
|
|
155
|
+
*/
|
|
156
|
+
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
157
|
+
throw new utils.GetAddressCancelledError();
|
|
145
158
|
}
|
|
146
|
-
|
|
147
|
-
|
|
159
|
+
const isRequestPendingError = isPendingWalletRequestPermissionError.isPendingWalletRequestPermissionError(error);
|
|
160
|
+
if (!isRequestPendingError) {
|
|
161
|
+
throw utils.MetaMaskError.fromError(error);
|
|
148
162
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (!isRequestPendingError) {
|
|
152
|
-
reject(utils.MetaMaskError.fromError(error));
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
yield waitForConnection.waitForConnection(this.getProvider());
|
|
156
|
-
}
|
|
163
|
+
else {
|
|
164
|
+
yield waitForConnection.waitForConnection(this.getProvider());
|
|
157
165
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
166
|
+
}
|
|
167
|
+
const accounts = yield this.getConnectedAccounts();
|
|
168
|
+
return accounts[0];
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
this.metaMaskSDK.off('display_uri', handleDisplayUri);
|
|
172
|
+
}
|
|
162
173
|
});
|
|
163
174
|
}
|
|
164
175
|
getConnectedAccountsSafely() {
|
|
@@ -318,7 +329,7 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
318
329
|
return viem.createWalletClient({
|
|
319
330
|
account: address,
|
|
320
331
|
chain: network ? ethereumCore.getOrMapViemChain(network) : this.getActiveChain(),
|
|
321
|
-
transport: viem.custom(provider),
|
|
332
|
+
transport: viem.custom(provider, this.providersConfig.httpTransportConfig),
|
|
322
333
|
});
|
|
323
334
|
}
|
|
324
335
|
toInt(chainId) {
|
|
@@ -372,7 +383,7 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
|
372
383
|
return true;
|
|
373
384
|
}
|
|
374
385
|
getConnectionUri() {
|
|
375
|
-
return
|
|
386
|
+
return _metaMaskDisplayUri !== null && _metaMaskDisplayUri !== void 0 ? _metaMaskDisplayUri : undefined;
|
|
376
387
|
}
|
|
377
388
|
}
|
|
378
389
|
// Utils
|
|
@@ -386,3 +397,5 @@ const waitForFocusWindowEvent = () => new Promise((resolve) => {
|
|
|
386
397
|
}).then(() => new Promise((resolve) => setTimeout(resolve, 1000)));
|
|
387
398
|
|
|
388
399
|
exports.MetaMaskConnector = MetaMaskConnector;
|
|
400
|
+
exports.eventTimeline = eventTimeline;
|
|
401
|
+
exports.setMetaMaskDisplayUri = setMetaMaskDisplayUri;
|
|
@@ -3,11 +3,12 @@ import { Account, Transport, WalletClient, Chain as ViemChain } from 'viem';
|
|
|
3
3
|
import { EthereumWalletConnectorOpts } from '@dynamic-labs/ethereum-core';
|
|
4
4
|
import { GetAddressOpts, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
|
|
5
5
|
import { InjectedWalletBase } from '../injected/InjectedWalletBase';
|
|
6
|
-
import { MetaMaskSDKDisplayUriState } from './utils/createMetaMaskSDKDisplayUriState';
|
|
7
6
|
export type MetaMaskConnectorProps = EthereumWalletConnectorOpts & {
|
|
8
7
|
appName: string;
|
|
9
8
|
appLogoUrl: string;
|
|
10
9
|
};
|
|
10
|
+
export declare const eventTimeline: import("@dynamic-labs/utils").EventTimeline<"connect" | "disconnect">;
|
|
11
|
+
export declare const setMetaMaskDisplayUri: (displayUri: string) => void;
|
|
11
12
|
export declare const clearMetaMaskSdk: () => void;
|
|
12
13
|
export declare class MetaMaskConnector extends InjectedWalletBase implements IWalletConnectConnector {
|
|
13
14
|
name: string;
|
|
@@ -21,7 +22,6 @@ export declare class MetaMaskConnector extends InjectedWalletBase implements IWa
|
|
|
21
22
|
getSupportedNetworks(): Promise<string[]>;
|
|
22
23
|
get metaMaskSDK(): MetaMaskSDK;
|
|
23
24
|
set metaMaskSDK(metaMaskSDK: MetaMaskSDK);
|
|
24
|
-
get metaMaskSDKDisplayUriState(): MetaMaskSDKDisplayUriState;
|
|
25
25
|
createMetaMaskSDK(): void;
|
|
26
26
|
endSession(): Promise<void>;
|
|
27
27
|
getAddress(opts?: GetAddressOpts): Promise<string | undefined>;
|
|
@@ -4,10 +4,9 @@ import { MetaMaskSDK } from '@metamask/sdk';
|
|
|
4
4
|
import { createWalletClient, custom, isHex, toHex } from 'viem';
|
|
5
5
|
import { getOrMapViemChain } from '@dynamic-labs/ethereum-core';
|
|
6
6
|
import { eventListenerHandlers } from '@dynamic-labs/wallet-connector-core';
|
|
7
|
-
import { createEventTimeline, PlatformService, isMobile, MetaMaskError, retryableFn, PlatformEventsService } from '@dynamic-labs/utils';
|
|
7
|
+
import { createEventTimeline, PlatformService, isMobile, GetAddressCancelledError, MetaMaskError, retryableFn, PlatformEventsService } from '@dynamic-labs/utils';
|
|
8
8
|
import { logger } from '../utils/logger.js';
|
|
9
9
|
import { InjectedWalletBase } from '../injected/InjectedWalletBase.js';
|
|
10
|
-
import { createMetaMaskSDKDisplayUriState } from './utils/createMetaMaskSDKDisplayUriState.js';
|
|
11
10
|
import { waitForConnection } from './utils/waitForConnection.js';
|
|
12
11
|
import { isPendingWalletRequestPermissionError } from './utils/isPendingWalletRequestPermissionError.js';
|
|
13
12
|
|
|
@@ -16,8 +15,11 @@ import { isPendingWalletRequestPermissionError } from './utils/isPendingWalletRe
|
|
|
16
15
|
* in these variables to avoid initializing it multiple times
|
|
17
16
|
*/
|
|
18
17
|
let _metaMaskSDK = null;
|
|
19
|
-
let
|
|
18
|
+
let _metaMaskDisplayUri = null;
|
|
20
19
|
const eventTimeline = createEventTimeline();
|
|
20
|
+
const setMetaMaskDisplayUri = (displayUri) => {
|
|
21
|
+
_metaMaskDisplayUri = displayUri;
|
|
22
|
+
};
|
|
21
23
|
class MetaMaskConnector extends InjectedWalletBase {
|
|
22
24
|
constructor(props) {
|
|
23
25
|
super(props);
|
|
@@ -40,6 +42,11 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
40
42
|
* to prevent a false negative
|
|
41
43
|
*/
|
|
42
44
|
this.isInAppBrowser = this.getIsInAppBrowser();
|
|
45
|
+
/**
|
|
46
|
+
* We can handle multiple connections in MetaMask only when the provider
|
|
47
|
+
* is installed on the browser.
|
|
48
|
+
*/
|
|
49
|
+
this.canHandleMultipleConnections = this.isInstalledOnBrowser();
|
|
43
50
|
if (!_metaMaskSDK) {
|
|
44
51
|
this.createMetaMaskSDK();
|
|
45
52
|
}
|
|
@@ -63,11 +70,6 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
63
70
|
set metaMaskSDK(metaMaskSDK) {
|
|
64
71
|
_metaMaskSDK = metaMaskSDK;
|
|
65
72
|
}
|
|
66
|
-
get metaMaskSDKDisplayUriState() {
|
|
67
|
-
if (!_metaMaskSDKDisplayUriState)
|
|
68
|
-
throw new Error('MetaMaskSDKDisplayUriState not initialized');
|
|
69
|
-
return _metaMaskSDKDisplayUriState;
|
|
70
|
-
}
|
|
71
73
|
createMetaMaskSDK() {
|
|
72
74
|
const dappMetadata = {
|
|
73
75
|
iconUrl: this.appLogoUrl,
|
|
@@ -86,8 +88,6 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
86
88
|
readonlyRPCMap: getReadonlyRPCMap(this.evmNetworkRpcMap()),
|
|
87
89
|
useDeeplink: true,
|
|
88
90
|
});
|
|
89
|
-
_metaMaskSDKDisplayUriState =
|
|
90
|
-
createMetaMaskSDKDisplayUriState(_metaMaskSDK);
|
|
91
91
|
}
|
|
92
92
|
endSession() {
|
|
93
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -99,7 +99,6 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
99
99
|
if (isMobile()) {
|
|
100
100
|
return this.metaMaskSDK.terminate().then(() => {
|
|
101
101
|
_metaMaskSDK = null;
|
|
102
|
-
_metaMaskSDKDisplayUriState = null;
|
|
103
102
|
return this.createMetaMaskSDK();
|
|
104
103
|
});
|
|
105
104
|
}
|
|
@@ -111,50 +110,62 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
111
110
|
}
|
|
112
111
|
getAddress(opts) {
|
|
113
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
113
|
+
yield this.metaMaskSDK.sdkInitPromise;
|
|
114
|
+
// QR Code flow
|
|
115
|
+
const handleDisplayUri = (displayUri) => {
|
|
116
|
+
var _a;
|
|
117
|
+
if (!displayUri)
|
|
118
|
+
return;
|
|
119
|
+
setMetaMaskDisplayUri(displayUri);
|
|
120
|
+
(_a = opts === null || opts === void 0 ? void 0 : opts.onDisplayUri) === null || _a === void 0 ? void 0 : _a.call(opts, displayUri);
|
|
121
|
+
};
|
|
122
|
+
if (!isMobile() && Boolean(opts === null || opts === void 0 ? void 0 : opts.onDisplayUri)) {
|
|
123
|
+
this.metaMaskSDK.on('display_uri', handleDisplayUri);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
128
126
|
// Deep link to MetaMask app in-app browser
|
|
129
127
|
if (this.shouldDeepLinkToMetaMaskInAppBrowser() &&
|
|
130
128
|
this.metadata.inAppBrowserUrl) {
|
|
131
129
|
// Redirect to the in-app browser and append the current url
|
|
132
130
|
PlatformService.openURL(`${this.metadata.inAppBrowserUrl}/${window.location.href}`);
|
|
133
|
-
resolve(undefined);
|
|
134
131
|
return;
|
|
135
132
|
}
|
|
136
133
|
// Connect to MetaMask
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
const initialConnectedAccounts = yield this.getConnectedAccountsSafely();
|
|
135
|
+
if (initialConnectedAccounts.length) {
|
|
136
|
+
return this.parseAddress(initialConnectedAccounts[0]);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
yield this.metaMaskSDK.connect();
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
/**
|
|
143
|
+
* In case of a getAddress call was already made and is pending
|
|
144
|
+
* and a new getAddress call is made after a endSession call, the
|
|
145
|
+
* MetaMask SDK will reject the original connect calls in the getAddress
|
|
146
|
+
* promise.
|
|
147
|
+
*
|
|
148
|
+
* In this case we want to cast the error to GetAddressCancelledError
|
|
149
|
+
* so the SDK knows the original getAddres call is cancelled and
|
|
150
|
+
* be clear to start the new getAddress flow
|
|
151
|
+
*/
|
|
152
|
+
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
153
|
+
throw new GetAddressCancelledError();
|
|
141
154
|
}
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
const isRequestPendingError = isPendingWalletRequestPermissionError(error);
|
|
156
|
+
if (!isRequestPendingError) {
|
|
157
|
+
throw MetaMaskError.fromError(error);
|
|
144
158
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (!isRequestPendingError) {
|
|
148
|
-
reject(MetaMaskError.fromError(error));
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
yield waitForConnection(this.getProvider());
|
|
152
|
-
}
|
|
159
|
+
else {
|
|
160
|
+
yield waitForConnection(this.getProvider());
|
|
153
161
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
162
|
+
}
|
|
163
|
+
const accounts = yield this.getConnectedAccounts();
|
|
164
|
+
return accounts[0];
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
this.metaMaskSDK.off('display_uri', handleDisplayUri);
|
|
168
|
+
}
|
|
158
169
|
});
|
|
159
170
|
}
|
|
160
171
|
getConnectedAccountsSafely() {
|
|
@@ -314,7 +325,7 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
314
325
|
return createWalletClient({
|
|
315
326
|
account: address,
|
|
316
327
|
chain: network ? getOrMapViemChain(network) : this.getActiveChain(),
|
|
317
|
-
transport: custom(provider),
|
|
328
|
+
transport: custom(provider, this.providersConfig.httpTransportConfig),
|
|
318
329
|
});
|
|
319
330
|
}
|
|
320
331
|
toInt(chainId) {
|
|
@@ -368,7 +379,7 @@ class MetaMaskConnector extends InjectedWalletBase {
|
|
|
368
379
|
return true;
|
|
369
380
|
}
|
|
370
381
|
getConnectionUri() {
|
|
371
|
-
return
|
|
382
|
+
return _metaMaskDisplayUri !== null && _metaMaskDisplayUri !== void 0 ? _metaMaskDisplayUri : undefined;
|
|
372
383
|
}
|
|
373
384
|
}
|
|
374
385
|
// Utils
|
|
@@ -381,4 +392,4 @@ const waitForFocusWindowEvent = () => new Promise((resolve) => {
|
|
|
381
392
|
PlatformEventsService.once('appFocused', resolve);
|
|
382
393
|
}).then(() => new Promise((resolve) => setTimeout(resolve, 1000)));
|
|
383
394
|
|
|
384
|
-
export { MetaMaskConnector };
|
|
395
|
+
export { MetaMaskConnector, eventTimeline, setMetaMaskDisplayUri };
|
|
@@ -18,6 +18,7 @@ class WalletConnectConnector extends ethereumCore.EthereumWalletConnector {
|
|
|
18
18
|
super(opts);
|
|
19
19
|
this.canConnectViaQrCode = true;
|
|
20
20
|
this.isWalletConnect = true;
|
|
21
|
+
this.canHandleMultipleConnections = false;
|
|
21
22
|
this.name = opts.walletName;
|
|
22
23
|
this.deepLinkPreference = opts.deepLinkPreference || 'native';
|
|
23
24
|
const storedChainId = utils.StorageService.getItem(WC_CURRENT_CHAIN_KEY);
|
|
@@ -123,7 +124,7 @@ class WalletConnectConnector extends ethereumCore.EthereumWalletConnector {
|
|
|
123
124
|
this.deepLinkIfApplicable(args.method);
|
|
124
125
|
return provider.request(args).catch(normalizeRpcError.normalizeRpcError);
|
|
125
126
|
},
|
|
126
|
-
}),
|
|
127
|
+
}, this.providersConfig.httpTransportConfig),
|
|
127
128
|
});
|
|
128
129
|
return walletClient;
|
|
129
130
|
}
|
|
@@ -12,6 +12,7 @@ export declare class WalletConnectConnector extends EthereumWalletConnector impl
|
|
|
12
12
|
name: string;
|
|
13
13
|
canConnectViaQrCode: boolean;
|
|
14
14
|
isWalletConnect: boolean;
|
|
15
|
+
canHandleMultipleConnections: boolean;
|
|
15
16
|
private deepLinkPreference;
|
|
16
17
|
constructor(opts: WalletConnectConnectorOpts);
|
|
17
18
|
init(): Promise<void>;
|
|
@@ -14,6 +14,7 @@ class WalletConnectConnector extends EthereumWalletConnector {
|
|
|
14
14
|
super(opts);
|
|
15
15
|
this.canConnectViaQrCode = true;
|
|
16
16
|
this.isWalletConnect = true;
|
|
17
|
+
this.canHandleMultipleConnections = false;
|
|
17
18
|
this.name = opts.walletName;
|
|
18
19
|
this.deepLinkPreference = opts.deepLinkPreference || 'native';
|
|
19
20
|
const storedChainId = StorageService.getItem(WC_CURRENT_CHAIN_KEY);
|
|
@@ -119,7 +120,7 @@ class WalletConnectConnector extends EthereumWalletConnector {
|
|
|
119
120
|
this.deepLinkIfApplicable(args.method);
|
|
120
121
|
return provider.request(args).catch(normalizeRpcError);
|
|
121
122
|
},
|
|
122
|
-
}),
|
|
123
|
+
}, this.providersConfig.httpTransportConfig),
|
|
123
124
|
});
|
|
124
125
|
return walletClient;
|
|
125
126
|
}
|
|
@@ -1,59 +0,0 @@
|
|
|
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
|
-
getConnectionUri: () => displayUri !== null && displayUri !== void 0 ? displayUri : undefined,
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
exports.createMetaMaskSDKDisplayUriState = createMetaMaskSDKDisplayUriState;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { MetaMaskSDK } from '@metamask/sdk';
|
|
2
|
-
export type MetaMaskSDKDisplayUriState = {
|
|
3
|
-
consumeDisplayUri: () => Promise<string | undefined>;
|
|
4
|
-
getConnectionUri: () => string | undefined;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Listens for the `display_uri` event emitted by the MetaMask SDK.
|
|
8
|
-
*
|
|
9
|
-
* The `display_uri` event is triggered during SDK initialization or when the `connect` method is called.
|
|
10
|
-
* Calling `terminate` in the MetaMask SDK resets the connection, and a new `display_uri` will only be emitted
|
|
11
|
-
* when `connect` is called again.
|
|
12
|
-
*
|
|
13
|
-
* This function manages the new `display_uri` received from these events.
|
|
14
|
-
*/
|
|
15
|
-
export declare const createMetaMaskSDKDisplayUriState: (metaMaskSDK: MetaMaskSDK) => MetaMaskSDKDisplayUriState;
|
|
@@ -1,55 +0,0 @@
|
|
|
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
|
-
getConnectionUri: () => displayUri !== null && displayUri !== void 0 ? displayUri : undefined,
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export { createMetaMaskSDKDisplayUriState };
|