@dynamic-labs/ethereum 4.85.0 → 4.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +13 -13
- package/src/EthereumWalletConnectors.cjs +3 -3
- package/src/EthereumWalletConnectors.js +3 -3
- package/src/index.cjs +5 -2
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/metaMask/MetaMaskConnector.cjs +0 -469
- package/src/metaMask/MetaMaskConnector.d.ts +0 -55
- package/src/metaMask/MetaMaskConnector.js +0 -463
- package/src/metaMask/utils/isPendingWalletRequestPermissionError.cjs +0 -11
- package/src/metaMask/utils/isPendingWalletRequestPermissionError.d.ts +0 -1
- package/src/metaMask/utils/isPendingWalletRequestPermissionError.js +0 -7
- package/src/metaMask/utils/waitForConnection.cjs +0 -10
- package/src/metaMask/utils/waitForConnection.d.ts +0 -2
- package/src/metaMask/utils/waitForConnection.js +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.87.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.86.0...v4.87.0) (2026-06-02)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **sdk-react-core:** instrument logout reason for Datadog observability DYNT-870 ([#11429](https://github.com/dynamic-labs/dynamic-auth/issues/11429)) ([8f9b3f3](https://github.com/dynamic-labs/dynamic-auth/commit/8f9b3f364dc711414ae59642c36f5f0a4cc4576a))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **sdk-react-core:** only flag auto-wallet abandoned on a sustained exit, not transient webview hide DYNT-870 ([#11428](https://github.com/dynamic-labs/dynamic-auth/issues/11428)) ([5984cdd](https://github.com/dynamic-labs/dynamic-auth/commit/5984cddb4ac04b226f6dd6ebe44340186902b012))
|
|
13
|
+
|
|
14
|
+
## [4.86.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.85.0...v4.86.0) (2026-06-01)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add support to new MetaMask SDK ([#11056](https://github.com/dynamic-labs/dynamic-auth/issues/11056)) ([8a6c973](https://github.com/dynamic-labs/dynamic-auth/commit/8a6c973876207256c06b04f6a16454f07446393d))
|
|
20
|
+
* **ethereum-gasless:** expose optional nonce on sign/send/relay ([#11422](https://github.com/dynamic-labs/dynamic-auth/issues/11422)) ([d2d074e](https://github.com/dynamic-labs/dynamic-auth/commit/d2d074ebe82452990281eba14a73f52a0af1e98b))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **sdk-react-core:** retry auto wallet creation on transient failures before erroring ([#11408](https://github.com/dynamic-labs/dynamic-auth/issues/11408)) ([8175460](https://github.com/dynamic-labs/dynamic-auth/commit/8175460bdee6f041ead0ea3f020cfd2168683239)), closes [#11399](https://github.com/dynamic-labs/dynamic-auth/issues/11399) [forward-mpc-client#286](https://github.com/dynamic-labs/forward-mpc-client/issues/286) [#11396](https://github.com/dynamic-labs/dynamic-auth/issues/11396)
|
|
26
|
+
|
|
2
27
|
## [4.85.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.84.1...v4.85.0) (2026-05-29)
|
|
3
28
|
|
|
4
29
|
|
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.
|
|
3
|
+
"version": "4.87.0",
|
|
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",
|
|
@@ -19,21 +19,21 @@
|
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@coinbase/wallet-sdk": "4.3.7",
|
|
22
|
-
"@dynamic-labs-connectors/base-account-evm": "4.
|
|
22
|
+
"@dynamic-labs-connectors/base-account-evm": "4.6.7",
|
|
23
|
+
"@dynamic-labs-connectors/metamask-evm": "4.6.7",
|
|
23
24
|
"@walletconnect/ethereum-provider": "2.21.5",
|
|
24
25
|
"eventemitter3": "5.0.1",
|
|
25
26
|
"buffer": "6.0.3",
|
|
26
|
-
"@
|
|
27
|
-
"@dynamic-labs/
|
|
28
|
-
"@dynamic-labs/
|
|
29
|
-
"@dynamic-labs/
|
|
30
|
-
"@dynamic-labs/
|
|
31
|
-
"@dynamic-labs/
|
|
32
|
-
"@dynamic-labs/
|
|
33
|
-
"@dynamic-labs/
|
|
34
|
-
"@dynamic-labs/
|
|
35
|
-
"@dynamic-labs/wallet-
|
|
36
|
-
"@dynamic-labs/wallet-connector-core": "4.85.0"
|
|
27
|
+
"@dynamic-labs/assert-package-version": "4.87.0",
|
|
28
|
+
"@dynamic-labs/embedded-wallet-evm": "4.87.0",
|
|
29
|
+
"@dynamic-labs/ethereum-core": "4.87.0",
|
|
30
|
+
"@dynamic-labs/logger": "4.87.0",
|
|
31
|
+
"@dynamic-labs/rpc-providers": "4.87.0",
|
|
32
|
+
"@dynamic-labs/types": "4.87.0",
|
|
33
|
+
"@dynamic-labs/utils": "4.87.0",
|
|
34
|
+
"@dynamic-labs/waas-evm": "4.87.0",
|
|
35
|
+
"@dynamic-labs/wallet-book": "4.87.0",
|
|
36
|
+
"@dynamic-labs/wallet-connector-core": "4.87.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"viem": "^2.45.3"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var baseAccountEvm = require('@dynamic-labs-connectors/base-account-evm');
|
|
7
|
+
var metamaskEvm = require('@dynamic-labs-connectors/metamask-evm');
|
|
7
8
|
var embeddedWalletEvm = require('@dynamic-labs/embedded-wallet-evm');
|
|
8
9
|
var waasEvm = require('@dynamic-labs/waas-evm');
|
|
9
10
|
require('../_virtual/_tslib.cjs');
|
|
@@ -20,7 +21,6 @@ var getWalletConnectConnector = require('./walletConnect/utils/getWalletConnectC
|
|
|
20
21
|
var FallbackEvmConnector = require('./injected/FallbackEvmConnector.cjs');
|
|
21
22
|
var fetchInjectedWalletConnectors = require('./injected/fetchInjectedWalletConnectors.cjs');
|
|
22
23
|
var coinbase = require('./coinbase/coinbase.cjs');
|
|
23
|
-
var MetaMaskConnector = require('./metaMask/MetaMaskConnector.cjs');
|
|
24
24
|
|
|
25
25
|
const EthereumWalletConnectors = (props) => {
|
|
26
26
|
const { useMetamaskSdk } = props;
|
|
@@ -33,7 +33,7 @@ const EthereumWalletConnectors = (props) => {
|
|
|
33
33
|
'intersend',
|
|
34
34
|
];
|
|
35
35
|
if (useMetamaskSdk) {
|
|
36
|
-
walletsWithCustomConnectors.push('metamask');
|
|
36
|
+
walletsWithCustomConnectors.push('metamask', 'metamaskevm');
|
|
37
37
|
}
|
|
38
38
|
return [
|
|
39
39
|
...fetchInjectedWalletConnectors.injectedWalletOverrides,
|
|
@@ -41,7 +41,7 @@ const EthereumWalletConnectors = (props) => {
|
|
|
41
41
|
...fetchWalletConnectWallets.fetchWalletConnectWallets(props),
|
|
42
42
|
...embeddedWalletEvm.TurnkeyEVMWalletConnectors(props),
|
|
43
43
|
...waasEvm.DynamicWaasEVMConnectors(),
|
|
44
|
-
...(useMetamaskSdk ?
|
|
44
|
+
...(useMetamaskSdk ? metamaskEvm.MetaMaskEvmWalletConnectors(props) : []),
|
|
45
45
|
coinbase.Coinbase,
|
|
46
46
|
...baseAccountEvm.createBaseAccountConnector(props.baseAccountSdkOpts)(props),
|
|
47
47
|
FallbackEvmConnector.FallbackEvmConnector,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { createBaseAccountConnector } from '@dynamic-labs-connectors/base-account-evm';
|
|
3
|
+
import { MetaMaskEvmWalletConnectors } from '@dynamic-labs-connectors/metamask-evm';
|
|
3
4
|
import { TurnkeyEVMWalletConnectors } from '@dynamic-labs/embedded-wallet-evm';
|
|
4
5
|
import { DynamicWaasEVMConnectors } from '@dynamic-labs/waas-evm';
|
|
5
6
|
import '../_virtual/_tslib.js';
|
|
@@ -16,7 +17,6 @@ import { getWalletConnectConnector } from './walletConnect/utils/getWalletConnec
|
|
|
16
17
|
import { FallbackEvmConnector } from './injected/FallbackEvmConnector.js';
|
|
17
18
|
import { injectedWalletOverrides, fetchInjectedWalletConnector } from './injected/fetchInjectedWalletConnectors.js';
|
|
18
19
|
import { Coinbase } from './coinbase/coinbase.js';
|
|
19
|
-
import { MetaMaskConnector } from './metaMask/MetaMaskConnector.js';
|
|
20
20
|
|
|
21
21
|
const EthereumWalletConnectors = (props) => {
|
|
22
22
|
const { useMetamaskSdk } = props;
|
|
@@ -29,7 +29,7 @@ const EthereumWalletConnectors = (props) => {
|
|
|
29
29
|
'intersend',
|
|
30
30
|
];
|
|
31
31
|
if (useMetamaskSdk) {
|
|
32
|
-
walletsWithCustomConnectors.push('metamask');
|
|
32
|
+
walletsWithCustomConnectors.push('metamask', 'metamaskevm');
|
|
33
33
|
}
|
|
34
34
|
return [
|
|
35
35
|
...injectedWalletOverrides,
|
|
@@ -37,7 +37,7 @@ const EthereumWalletConnectors = (props) => {
|
|
|
37
37
|
...fetchWalletConnectWallets(props),
|
|
38
38
|
...TurnkeyEVMWalletConnectors(props),
|
|
39
39
|
...DynamicWaasEVMConnectors(),
|
|
40
|
-
...(useMetamaskSdk ?
|
|
40
|
+
...(useMetamaskSdk ? MetaMaskEvmWalletConnectors(props) : []),
|
|
41
41
|
Coinbase,
|
|
42
42
|
...createBaseAccountConnector(props.baseAccountSdkOpts)(props),
|
|
43
43
|
FallbackEvmConnector,
|
package/src/index.cjs
CHANGED
|
@@ -24,7 +24,7 @@ require('@dynamic-labs/utils');
|
|
|
24
24
|
require('@dynamic-labs/wallet-connector-core');
|
|
25
25
|
require('./walletConnect/WalletConnectProvider/WalletConnectProvider.cjs');
|
|
26
26
|
var EvmWalletConnectConnectors = require('./walletConnect/EvmWalletConnectConnectors.cjs');
|
|
27
|
-
var
|
|
27
|
+
var metamaskEvm = require('@dynamic-labs-connectors/metamask-evm');
|
|
28
28
|
var getConnectorConstructorForEip6963Wallet = require('./utils/getConnectorConstructorForEip6963Wallet/getConnectorConstructorForEip6963Wallet.cjs');
|
|
29
29
|
|
|
30
30
|
assertPackageVersion.assertPackageVersion('@dynamic-labs/ethereum', _package.version);
|
|
@@ -53,5 +53,8 @@ exports.createInjectedConnector = createInjectedConnector.createInjectedConnecto
|
|
|
53
53
|
exports.EthereumWalletConnectors = EthereumWalletConnectors.EthereumWalletConnectors;
|
|
54
54
|
exports.EthereumWalletConnectorsWithConfig = EthereumWalletConnectorsWithConfig.EthereumWalletConnectorsWithConfig;
|
|
55
55
|
exports.EvmWalletConnectConnectors = EvmWalletConnectConnectors.EvmWalletConnectConnectors;
|
|
56
|
-
exports
|
|
56
|
+
Object.defineProperty(exports, 'MetaMaskConnector', {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
get: function () { return metamaskEvm.MetaMaskEvmWalletConnector; }
|
|
59
|
+
});
|
|
57
60
|
exports.getConnectorConstructorForEip6963Wallet = getConnectorConstructorForEip6963Wallet.getConnectorConstructorForEip6963Wallet;
|
package/src/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { createInjectedConnector } from './utils/createInjectedConnector';
|
|
|
8
8
|
export { EthereumWalletConnectors } from './EthereumWalletConnectors';
|
|
9
9
|
export { EthereumWalletConnectorsWithConfig } from './EthereumWalletConnectorsWithConfig';
|
|
10
10
|
export { EvmWalletConnectConnectors } from './walletConnect';
|
|
11
|
-
export { MetaMaskConnector } from '
|
|
11
|
+
export { MetaMaskEvmWalletConnector as MetaMaskConnector } from '@dynamic-labs-connectors/metamask-evm';
|
|
12
12
|
export { isEthereumWallet, EthereumWalletConnector, createConnector, } from '@dynamic-labs/ethereum-core';
|
|
13
13
|
export { getConnectorConstructorForEip6963Wallet } from './utils/getConnectorConstructorForEip6963Wallet';
|
package/src/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import '@dynamic-labs/utils';
|
|
|
20
20
|
import '@dynamic-labs/wallet-connector-core';
|
|
21
21
|
import './walletConnect/WalletConnectProvider/WalletConnectProvider.js';
|
|
22
22
|
export { EvmWalletConnectConnectors } from './walletConnect/EvmWalletConnectConnectors.js';
|
|
23
|
-
export { MetaMaskConnector } from '
|
|
23
|
+
export { MetaMaskEvmWalletConnector as MetaMaskConnector } from '@dynamic-labs-connectors/metamask-evm';
|
|
24
24
|
export { getConnectorConstructorForEip6963Wallet } from './utils/getConnectorConstructorForEip6963Wallet/getConnectorConstructorForEip6963Wallet.js';
|
|
25
25
|
|
|
26
26
|
assertPackageVersion('@dynamic-labs/ethereum', version);
|
|
@@ -1,469 +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
|
-
var sdk = require('@metamask/sdk');
|
|
8
|
-
var viem = require('viem');
|
|
9
|
-
var ethereumCore = require('@dynamic-labs/ethereum-core');
|
|
10
|
-
var utils = require('@dynamic-labs/utils');
|
|
11
|
-
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
12
|
-
var InjectedWalletBase = require('../injected/InjectedWalletBase.cjs');
|
|
13
|
-
var logger = require('../utils/logger.cjs');
|
|
14
|
-
var isPendingWalletRequestPermissionError = require('./utils/isPendingWalletRequestPermissionError.cjs');
|
|
15
|
-
var waitForConnection = require('./utils/waitForConnection.cjs');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* The MetaMask SDK must be initialized only once, so we store the instance
|
|
19
|
-
* in these variables to avoid initializing it multiple times
|
|
20
|
-
*/
|
|
21
|
-
let _metaMaskSDK = null;
|
|
22
|
-
let _metaMaskDisplayUri = null;
|
|
23
|
-
let _metaMaskConnectUri = null;
|
|
24
|
-
const eventTimeline = utils.createEventTimeline();
|
|
25
|
-
const setMetaMaskDisplayUri = (displayUri) => {
|
|
26
|
-
_metaMaskDisplayUri = displayUri;
|
|
27
|
-
};
|
|
28
|
-
class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
|
|
29
|
-
constructor(props) {
|
|
30
|
-
super(props);
|
|
31
|
-
this.name = 'MetaMask';
|
|
32
|
-
this.overrideKey = 'metamask';
|
|
33
|
-
this.canConnectViaQrCode = true;
|
|
34
|
-
this.isInAppBrowser = false;
|
|
35
|
-
this.appName = props.appName;
|
|
36
|
-
this.appLogoUrl = props.appLogoUrl;
|
|
37
|
-
/**
|
|
38
|
-
* The isInAppBrowser must be calculated before initializing the MetaMask SDK.
|
|
39
|
-
*
|
|
40
|
-
* The isInAppBrowser is calculated by checking if the window provider is installed
|
|
41
|
-
* in the browser and if it is running on a mobile device.
|
|
42
|
-
*
|
|
43
|
-
* But the MetaMask SDK will inject its own provider to the window if not provider is injected.
|
|
44
|
-
* This means the MetaMask SDK can interfere with the isInAppBrowser calculation.
|
|
45
|
-
*
|
|
46
|
-
* So we need to calculate the isInAppBrowser before initializing the MetaMask SDK
|
|
47
|
-
* to prevent a false negative
|
|
48
|
-
*/
|
|
49
|
-
this.isInAppBrowser = this.getIsInAppBrowser();
|
|
50
|
-
/**
|
|
51
|
-
* We can handle multiple connections in MetaMask only when the provider
|
|
52
|
-
* is installed on the browser.
|
|
53
|
-
*/
|
|
54
|
-
this.canHandleMultipleConnections = this.isInstalledOnBrowser();
|
|
55
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] constructor', {
|
|
56
|
-
hasMetaMaskSDK: Boolean(_metaMaskSDK),
|
|
57
|
-
});
|
|
58
|
-
if (!_metaMaskSDK) {
|
|
59
|
-
this.createMetaMaskSDK();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
isInstalledOnBrowser() {
|
|
63
|
-
var _a;
|
|
64
|
-
const metaMaskEip6963Provider = (_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns);
|
|
65
|
-
const isInstalled = Boolean(metaMaskEip6963Provider);
|
|
66
|
-
return isInstalled;
|
|
67
|
-
}
|
|
68
|
-
getSupportedNetworks() {
|
|
69
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
return this.evmNetworks.map((network) => network.chainId.toString());
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
get metaMaskSDK() {
|
|
74
|
-
if (!_metaMaskSDK)
|
|
75
|
-
throw new Error('MetaMaskSDK not initialized');
|
|
76
|
-
return _metaMaskSDK;
|
|
77
|
-
}
|
|
78
|
-
set metaMaskSDK(metaMaskSDK) {
|
|
79
|
-
_metaMaskSDK = metaMaskSDK;
|
|
80
|
-
}
|
|
81
|
-
createMetaMaskSDK() {
|
|
82
|
-
const dappMetadata = {
|
|
83
|
-
iconUrl: this.appLogoUrl,
|
|
84
|
-
name: this.appName,
|
|
85
|
-
url: utils.PlatformService.getOrigin(),
|
|
86
|
-
};
|
|
87
|
-
logger.logger.debug('[MetaMaskConnector] createMetaMaskSDK - creating sdk', {
|
|
88
|
-
dappMetadata,
|
|
89
|
-
});
|
|
90
|
-
_metaMaskSDK = new sdk.MetaMaskSDK({
|
|
91
|
-
checkInstallationImmediately: true,
|
|
92
|
-
dappMetadata,
|
|
93
|
-
enableAnalytics: false,
|
|
94
|
-
extensionOnly: this.isInstalledOnBrowser(),
|
|
95
|
-
headless: true,
|
|
96
|
-
injectProvider: false,
|
|
97
|
-
openDeeplink: (url) => {
|
|
98
|
-
if (url.includes('://connect')) {
|
|
99
|
-
_metaMaskConnectUri = url;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
_metaMaskConnectUri = null;
|
|
103
|
-
}
|
|
104
|
-
utils.PlatformService.openURL(url);
|
|
105
|
-
},
|
|
106
|
-
preferDesktop: !utils.isMobile(),
|
|
107
|
-
readonlyRPCMap: getReadonlyRPCMap(this.evmNetworkRpcMap()),
|
|
108
|
-
useDeeplink: true,
|
|
109
|
-
});
|
|
110
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] createMetaMaskSDK - created sdk', { _metaMaskSDK });
|
|
111
|
-
}
|
|
112
|
-
endSession() {
|
|
113
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
114
|
-
eventTimeline.postEvent('disconnect');
|
|
115
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] endSession - terminating sdk');
|
|
116
|
-
/**
|
|
117
|
-
* The MetaMask SDK must be terminated and reinitialized on mobile
|
|
118
|
-
* to prevent deeplinks not working
|
|
119
|
-
*/
|
|
120
|
-
if (utils.isMobile()) {
|
|
121
|
-
return this.metaMaskSDK.terminate().then(() => {
|
|
122
|
-
_metaMaskSDK = null;
|
|
123
|
-
_metaMaskConnectUri = null;
|
|
124
|
-
return this.createMetaMaskSDK();
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Just terminate the SDK on desktop
|
|
129
|
-
*/
|
|
130
|
-
return this.metaMaskSDK.terminate();
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
getAddress(opts) {
|
|
134
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - waiting for sdk init');
|
|
136
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
137
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - sdk init promise resolved');
|
|
138
|
-
// QR Code flow
|
|
139
|
-
const handleDisplayUri = (displayUri) => {
|
|
140
|
-
var _a;
|
|
141
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] handleDisplayUri', { displayUri });
|
|
142
|
-
if (!displayUri)
|
|
143
|
-
return;
|
|
144
|
-
setMetaMaskDisplayUri(displayUri);
|
|
145
|
-
(_a = opts === null || opts === void 0 ? void 0 : opts.onDisplayUri) === null || _a === void 0 ? void 0 : _a.call(opts, displayUri);
|
|
146
|
-
};
|
|
147
|
-
if (!utils.isMobile() && Boolean(opts === null || opts === void 0 ? void 0 : opts.onDisplayUri)) {
|
|
148
|
-
this.metaMaskSDK.on('display_uri', handleDisplayUri);
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
// Deep link to MetaMask app in-app browser
|
|
152
|
-
if (this.shouldDeepLinkToMetaMaskInAppBrowser() &&
|
|
153
|
-
this.metadata.inAppBrowserUrl) {
|
|
154
|
-
const inAppBrowserCompiledTemplate = utils.template(this.metadata.inAppBrowserUrl);
|
|
155
|
-
const { href } = utils.PlatformService.getUrl();
|
|
156
|
-
const deepLink = inAppBrowserCompiledTemplate({
|
|
157
|
-
dappURI: href,
|
|
158
|
-
});
|
|
159
|
-
// Redirect to the in-app browser and append the current url
|
|
160
|
-
utils.PlatformService.openURL(deepLink);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - getting initial connected accounts');
|
|
164
|
-
// Connect to MetaMask
|
|
165
|
-
const initialConnectedAccounts = yield this.getConnectedAccountsSafely();
|
|
166
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - got initial connected accounts', { initialConnectedAccounts });
|
|
167
|
-
if (initialConnectedAccounts.length) {
|
|
168
|
-
return this.parseAddress(initialConnectedAccounts[0]);
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - connecting to metaMask');
|
|
172
|
-
const response = yield this.metaMaskSDK.connect();
|
|
173
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - connected to metaMask', { response });
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - error connecting to metaMask', { error });
|
|
177
|
-
/**
|
|
178
|
-
* In case of a getAddress call was already made and is pending
|
|
179
|
-
* and a new getAddress call is made after a endSession call, the
|
|
180
|
-
* MetaMask SDK will reject the original connect calls in the getAddress
|
|
181
|
-
* promise.
|
|
182
|
-
*
|
|
183
|
-
* In this case we want to cast the error to GetAddressCancelledError
|
|
184
|
-
* so the SDK knows the original getAddres call is cancelled and
|
|
185
|
-
* be clear to start the new getAddress flow
|
|
186
|
-
*/
|
|
187
|
-
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
188
|
-
throw new utils.GetAddressCancelledError();
|
|
189
|
-
}
|
|
190
|
-
const isRequestPendingError = isPendingWalletRequestPermissionError.isPendingWalletRequestPermissionError(error);
|
|
191
|
-
if (!isRequestPendingError) {
|
|
192
|
-
throw utils.MetaMaskError.fromError(error);
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - error connection - waiting for connection');
|
|
196
|
-
// Get provider again after connect() attempt - it might be available now
|
|
197
|
-
const providerAfterConnect = this.getProvider();
|
|
198
|
-
if (providerAfterConnect) {
|
|
199
|
-
yield waitForConnection.waitForConnection(providerAfterConnect);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - getting connected accounts');
|
|
204
|
-
const accounts = yield this.getConnectedAccounts();
|
|
205
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - got connected accounts', { accounts });
|
|
206
|
-
return accounts[0];
|
|
207
|
-
}
|
|
208
|
-
finally {
|
|
209
|
-
this.metaMaskSDK.off('display_uri', handleDisplayUri);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
getConnectedAccountsSafely() {
|
|
214
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
215
|
-
try {
|
|
216
|
-
const connectedAccounts = yield this.getConnectedAccounts();
|
|
217
|
-
return connectedAccounts;
|
|
218
|
-
}
|
|
219
|
-
catch (err) {
|
|
220
|
-
logger.logger.error(err);
|
|
221
|
-
return [];
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
getConnectedAccounts() {
|
|
226
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
227
|
-
// Wait for for MetaMask SDK to initialize
|
|
228
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
229
|
-
const provider = this.getProvider();
|
|
230
|
-
if (!provider) {
|
|
231
|
-
return [];
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* The eth_accounts method can hang on mobile devices when
|
|
235
|
-
* the MetaMask SDK has not connected yet. So we use a retryable
|
|
236
|
-
* to ensure the timeout will be respected
|
|
237
|
-
*/
|
|
238
|
-
const accounts = yield utils.retryableFn(() => provider.request({
|
|
239
|
-
method: 'eth_accounts',
|
|
240
|
-
params: [],
|
|
241
|
-
}), {
|
|
242
|
-
fallbackValue: [],
|
|
243
|
-
timeoutMs: 1000,
|
|
244
|
-
});
|
|
245
|
-
if (!(accounts === null || accounts === void 0 ? void 0 : accounts.length)) {
|
|
246
|
-
return [];
|
|
247
|
-
}
|
|
248
|
-
return accounts.map(this.parseAddress);
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
signMessage(messageToSign) {
|
|
252
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
253
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - waiting for sdk init');
|
|
254
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
255
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - sdk init promise resolved');
|
|
256
|
-
/**
|
|
257
|
-
* Should wait for the window to be focused on mobile
|
|
258
|
-
* to account for the user moving between the MetaMaskApp
|
|
259
|
-
* and the browser
|
|
260
|
-
*/
|
|
261
|
-
const windowFocusPromiseForMobile = !this.isInAppBrowser && utils.isMobile()
|
|
262
|
-
? waitForFocusWindowEvent()
|
|
263
|
-
: Promise.resolve();
|
|
264
|
-
const provider = this.getProvider();
|
|
265
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - got provider', { provider });
|
|
266
|
-
if (!provider) {
|
|
267
|
-
return undefined;
|
|
268
|
-
}
|
|
269
|
-
const [selectedAddress] = yield this.getConnectedAccounts();
|
|
270
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - got selected address', { selectedAddress });
|
|
271
|
-
if (!selectedAddress) {
|
|
272
|
-
return undefined;
|
|
273
|
-
}
|
|
274
|
-
const walletClient = this.getWalletClientForAddress(selectedAddress);
|
|
275
|
-
if (!walletClient)
|
|
276
|
-
return undefined;
|
|
277
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - will sign', { messageToSign });
|
|
278
|
-
const signature = yield walletClient.signMessage({
|
|
279
|
-
message: messageToSign,
|
|
280
|
-
});
|
|
281
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - will wait for window focus');
|
|
282
|
-
yield windowFocusPromiseForMobile;
|
|
283
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - signed', { signature });
|
|
284
|
-
return signature;
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
chooseAccountsToConnect() {
|
|
288
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
289
|
-
return [];
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
getWalletClient(chainId) {
|
|
293
|
-
const provider = this.getProvider();
|
|
294
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getWalletClient - got provider', { provider });
|
|
295
|
-
if (!provider) {
|
|
296
|
-
return undefined;
|
|
297
|
-
}
|
|
298
|
-
const selectedAddress = provider.getSelectedAddress();
|
|
299
|
-
return this.getWalletClientForAddress(selectedAddress || undefined, chainId);
|
|
300
|
-
}
|
|
301
|
-
get rdns() {
|
|
302
|
-
const { rdns } = this.metadata;
|
|
303
|
-
if (!rdns) {
|
|
304
|
-
throw new Error('rdns not found in metadata');
|
|
305
|
-
}
|
|
306
|
-
return rdns;
|
|
307
|
-
}
|
|
308
|
-
setupEventListeners() {
|
|
309
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
310
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
311
|
-
const metaMaskProvider = this.getProvider();
|
|
312
|
-
if (!metaMaskProvider) {
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
const { handleAccountChange, handleChainChange, handleDisconnect } = walletConnectorCore.eventListenerHandlers(this);
|
|
316
|
-
const handleAccountsChangedFromMetaMask = (accounts) => {
|
|
317
|
-
/**
|
|
318
|
-
* MetaMask emits an account changed event when the wallet is disconnected
|
|
319
|
-
* so we ignore the accountsChanged event if the disconnect event was recent
|
|
320
|
-
*/
|
|
321
|
-
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
325
|
-
// @ts-ignore
|
|
326
|
-
handleAccountChange(accounts);
|
|
327
|
-
};
|
|
328
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
329
|
-
// @ts-ignore
|
|
330
|
-
metaMaskProvider.on('accountsChanged', handleAccountsChangedFromMetaMask);
|
|
331
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
332
|
-
// @ts-ignore
|
|
333
|
-
metaMaskProvider.on('chainChanged', handleChainChange);
|
|
334
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
335
|
-
// @ts-ignore
|
|
336
|
-
metaMaskProvider.on('disconnect', handleDisconnect);
|
|
337
|
-
this.teardownEventListeners = () => {
|
|
338
|
-
metaMaskProvider.off('accountsChanged', handleAccountsChangedFromMetaMask);
|
|
339
|
-
metaMaskProvider.off('chainChanged', handleChainChange);
|
|
340
|
-
metaMaskProvider.off('disconnect', handleDisconnect);
|
|
341
|
-
};
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* This override is necessary to wait for the MetaMask SDK to initialize
|
|
346
|
-
* before calling the super method. Otherwise, the super method may fail
|
|
347
|
-
* to fetch the provider
|
|
348
|
-
*/
|
|
349
|
-
getNetwork() {
|
|
350
|
-
const _super = Object.create(null, {
|
|
351
|
-
getNetwork: { get: () => super.getNetwork }
|
|
352
|
-
});
|
|
353
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
354
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - waiting for sdk init');
|
|
355
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
356
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - sdk init promise resolved');
|
|
357
|
-
const net = yield _super.getNetwork.call(this);
|
|
358
|
-
logger.logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - got network', { network: net });
|
|
359
|
-
return net;
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
// Utils
|
|
363
|
-
getProvider() {
|
|
364
|
-
var _a, _b;
|
|
365
|
-
try {
|
|
366
|
-
return ((_b = (_a = this.metaMaskSDK.getProvider()) !== null && _a !== void 0 ? _a : this.metaMaskSDK.getMobileProvider()) !== null && _b !== void 0 ? _b : undefined);
|
|
367
|
-
}
|
|
368
|
-
catch (_c) {
|
|
369
|
-
// If getMobileProvider throws (mobile provider not ready), return undefined
|
|
370
|
-
return undefined;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
evmNetworkByChainId(chainId) {
|
|
374
|
-
return this.evmNetworks.find((network) => network.chainId === chainId);
|
|
375
|
-
}
|
|
376
|
-
getWalletClientForAddress(address, chainId) {
|
|
377
|
-
var _a, _b;
|
|
378
|
-
const provider = this.getProvider();
|
|
379
|
-
if (!provider) {
|
|
380
|
-
return undefined;
|
|
381
|
-
}
|
|
382
|
-
const effectiveChainId = (_b = (_a = this.toInt(chainId)) !== null && _a !== void 0 ? _a : this.getCurrentChainId()) !== null && _b !== void 0 ? _b : '1';
|
|
383
|
-
const network = this.evmNetworkByChainId(effectiveChainId);
|
|
384
|
-
return viem.createWalletClient({
|
|
385
|
-
account: address,
|
|
386
|
-
chain: network ? ethereumCore.getOrMapViemChain(network) : this.getActiveChain(),
|
|
387
|
-
transport: viem.custom(provider, this.providersConfig.httpTransportConfig),
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
toInt(chainId) {
|
|
391
|
-
if (!chainId)
|
|
392
|
-
return undefined;
|
|
393
|
-
try {
|
|
394
|
-
return parseInt(chainId);
|
|
395
|
-
}
|
|
396
|
-
catch (err) {
|
|
397
|
-
logger.logger.debug(err);
|
|
398
|
-
return undefined;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
getCurrentChainId() {
|
|
402
|
-
const provider = this.getProvider();
|
|
403
|
-
if (!provider) {
|
|
404
|
-
return undefined;
|
|
405
|
-
}
|
|
406
|
-
const chainId = provider.getChainId();
|
|
407
|
-
if (viem.isHex(chainId)) {
|
|
408
|
-
return parseInt(chainId);
|
|
409
|
-
}
|
|
410
|
-
return chainId;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Checks if the current environment is the MetaMask in-app browser
|
|
414
|
-
* by checking if the MetaMask provider is installed in the window object
|
|
415
|
-
* on a mobile device
|
|
416
|
-
*/
|
|
417
|
-
getIsInAppBrowser() {
|
|
418
|
-
var _a, _b;
|
|
419
|
-
if (!utils.isMobile())
|
|
420
|
-
return false;
|
|
421
|
-
const provider = ((_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns)) ||
|
|
422
|
-
((_b = this.ethProviderHelper) === null || _b === void 0 ? void 0 : _b.getInjectedProvider());
|
|
423
|
-
return Boolean(provider);
|
|
424
|
-
}
|
|
425
|
-
shouldDeepLinkToMetaMaskInAppBrowser() {
|
|
426
|
-
// Not in an in-app browser
|
|
427
|
-
if (this.isInAppBrowser) {
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
// Not a mobile device
|
|
431
|
-
if (!utils.isMobile()) {
|
|
432
|
-
return false;
|
|
433
|
-
}
|
|
434
|
-
// SDK is configured to use the in-app browser
|
|
435
|
-
if (this.mobileExperience !== 'in-app-browser') {
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
// Wallet does not have an in-app browser link
|
|
439
|
-
if (!this.metadata.inAppBrowserUrl) {
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
// We don't want to deep link to the in-app browser when already in the in-app browser
|
|
443
|
-
if (navigator.userAgent.match(/metamaskmobile/i)) {
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
return true;
|
|
447
|
-
}
|
|
448
|
-
getConnectionUri() {
|
|
449
|
-
return _metaMaskDisplayUri !== null && _metaMaskDisplayUri !== void 0 ? _metaMaskDisplayUri : undefined;
|
|
450
|
-
}
|
|
451
|
-
retryDeeplinkConnection() {
|
|
452
|
-
if (_metaMaskConnectUri) {
|
|
453
|
-
utils.PlatformService.openURL(_metaMaskConnectUri);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
// Utils
|
|
458
|
-
const getReadonlyRPCMap = (evmNetworkRpcMap) => Object.keys(evmNetworkRpcMap).reduce((acc, chainId) => (Object.assign(Object.assign({}, acc), { [viem.toHex(parseInt(chainId))]: evmNetworkRpcMap[chainId] })), {});
|
|
459
|
-
/**
|
|
460
|
-
* Waits for the focus page event and await for an extra second
|
|
461
|
-
* This is necessary to ensure the verify call will succeed
|
|
462
|
-
*/
|
|
463
|
-
const waitForFocusWindowEvent = () => new Promise((resolve) => {
|
|
464
|
-
utils.PlatformEventsService.once('appFocused', resolve);
|
|
465
|
-
}).then(() => new Promise((resolve) => setTimeout(resolve, 1000)));
|
|
466
|
-
|
|
467
|
-
exports.MetaMaskConnector = MetaMaskConnector;
|
|
468
|
-
exports.eventTimeline = eventTimeline;
|
|
469
|
-
exports.setMetaMaskDisplayUri = setMetaMaskDisplayUri;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { MetaMaskSDK } from '@metamask/sdk';
|
|
2
|
-
import { Account, Transport, Chain as ViemChain, WalletClient } from 'viem';
|
|
3
|
-
import { EthereumWalletConnectorOpts } from '@dynamic-labs/ethereum-core';
|
|
4
|
-
import { GetAddressOpts, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
|
|
5
|
-
import { InjectedWalletBase } from '../injected/InjectedWalletBase';
|
|
6
|
-
export type MetaMaskConnectorProps = EthereumWalletConnectorOpts & {
|
|
7
|
-
appName: string;
|
|
8
|
-
appLogoUrl: string;
|
|
9
|
-
};
|
|
10
|
-
export declare const eventTimeline: import("@dynamic-labs/utils").EventTimeline<"connect" | "disconnect">;
|
|
11
|
-
export declare const setMetaMaskDisplayUri: (displayUri: string) => void;
|
|
12
|
-
export declare const clearMetaMaskSdk: () => void;
|
|
13
|
-
export declare class MetaMaskConnector extends InjectedWalletBase implements IWalletConnectConnector {
|
|
14
|
-
name: string;
|
|
15
|
-
overrideKey: string;
|
|
16
|
-
canConnectViaQrCode: boolean;
|
|
17
|
-
private appName;
|
|
18
|
-
private appLogoUrl;
|
|
19
|
-
private isInAppBrowser;
|
|
20
|
-
constructor(props: MetaMaskConnectorProps);
|
|
21
|
-
isInstalledOnBrowser(): boolean;
|
|
22
|
-
getSupportedNetworks(): Promise<string[]>;
|
|
23
|
-
get metaMaskSDK(): MetaMaskSDK;
|
|
24
|
-
set metaMaskSDK(metaMaskSDK: MetaMaskSDK);
|
|
25
|
-
createMetaMaskSDK(): void;
|
|
26
|
-
endSession(): Promise<void>;
|
|
27
|
-
getAddress(opts?: GetAddressOpts): Promise<string | undefined>;
|
|
28
|
-
private getConnectedAccountsSafely;
|
|
29
|
-
getConnectedAccounts(): Promise<string[]>;
|
|
30
|
-
signMessage(messageToSign: string): Promise<string | undefined>;
|
|
31
|
-
chooseAccountsToConnect(): Promise<never[]>;
|
|
32
|
-
getWalletClient(chainId?: string): WalletClient<Transport, ViemChain, Account> | undefined;
|
|
33
|
-
get rdns(): string;
|
|
34
|
-
setupEventListeners(): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* This override is necessary to wait for the MetaMask SDK to initialize
|
|
37
|
-
* before calling the super method. Otherwise, the super method may fail
|
|
38
|
-
* to fetch the provider
|
|
39
|
-
*/
|
|
40
|
-
getNetwork(): Promise<number | undefined>;
|
|
41
|
-
private getProvider;
|
|
42
|
-
private evmNetworkByChainId;
|
|
43
|
-
private getWalletClientForAddress;
|
|
44
|
-
private toInt;
|
|
45
|
-
private getCurrentChainId;
|
|
46
|
-
/**
|
|
47
|
-
* Checks if the current environment is the MetaMask in-app browser
|
|
48
|
-
* by checking if the MetaMask provider is installed in the window object
|
|
49
|
-
* on a mobile device
|
|
50
|
-
*/
|
|
51
|
-
private getIsInAppBrowser;
|
|
52
|
-
private shouldDeepLinkToMetaMaskInAppBrowser;
|
|
53
|
-
getConnectionUri(): string | undefined;
|
|
54
|
-
retryDeeplinkConnection(): void;
|
|
55
|
-
}
|
|
@@ -1,463 +0,0 @@
|
|
|
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 { getOrMapViemChain } from '@dynamic-labs/ethereum-core';
|
|
6
|
-
import { createEventTimeline, PlatformService, isMobile, template, GetAddressCancelledError, MetaMaskError, retryableFn, PlatformEventsService } from '@dynamic-labs/utils';
|
|
7
|
-
import { eventListenerHandlers } from '@dynamic-labs/wallet-connector-core';
|
|
8
|
-
import { InjectedWalletBase } from '../injected/InjectedWalletBase.js';
|
|
9
|
-
import { logger } from '../utils/logger.js';
|
|
10
|
-
import { isPendingWalletRequestPermissionError } from './utils/isPendingWalletRequestPermissionError.js';
|
|
11
|
-
import { waitForConnection } from './utils/waitForConnection.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* The MetaMask SDK must be initialized only once, so we store the instance
|
|
15
|
-
* in these variables to avoid initializing it multiple times
|
|
16
|
-
*/
|
|
17
|
-
let _metaMaskSDK = null;
|
|
18
|
-
let _metaMaskDisplayUri = null;
|
|
19
|
-
let _metaMaskConnectUri = null;
|
|
20
|
-
const eventTimeline = createEventTimeline();
|
|
21
|
-
const setMetaMaskDisplayUri = (displayUri) => {
|
|
22
|
-
_metaMaskDisplayUri = displayUri;
|
|
23
|
-
};
|
|
24
|
-
class MetaMaskConnector extends InjectedWalletBase {
|
|
25
|
-
constructor(props) {
|
|
26
|
-
super(props);
|
|
27
|
-
this.name = 'MetaMask';
|
|
28
|
-
this.overrideKey = 'metamask';
|
|
29
|
-
this.canConnectViaQrCode = true;
|
|
30
|
-
this.isInAppBrowser = false;
|
|
31
|
-
this.appName = props.appName;
|
|
32
|
-
this.appLogoUrl = props.appLogoUrl;
|
|
33
|
-
/**
|
|
34
|
-
* The isInAppBrowser must be calculated before initializing the MetaMask SDK.
|
|
35
|
-
*
|
|
36
|
-
* The isInAppBrowser is calculated by checking if the window provider is installed
|
|
37
|
-
* in the browser and if it is running on a mobile device.
|
|
38
|
-
*
|
|
39
|
-
* But the MetaMask SDK will inject its own provider to the window if not provider is injected.
|
|
40
|
-
* This means the MetaMask SDK can interfere with the isInAppBrowser calculation.
|
|
41
|
-
*
|
|
42
|
-
* So we need to calculate the isInAppBrowser before initializing the MetaMask SDK
|
|
43
|
-
* to prevent a false negative
|
|
44
|
-
*/
|
|
45
|
-
this.isInAppBrowser = this.getIsInAppBrowser();
|
|
46
|
-
/**
|
|
47
|
-
* We can handle multiple connections in MetaMask only when the provider
|
|
48
|
-
* is installed on the browser.
|
|
49
|
-
*/
|
|
50
|
-
this.canHandleMultipleConnections = this.isInstalledOnBrowser();
|
|
51
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] constructor', {
|
|
52
|
-
hasMetaMaskSDK: Boolean(_metaMaskSDK),
|
|
53
|
-
});
|
|
54
|
-
if (!_metaMaskSDK) {
|
|
55
|
-
this.createMetaMaskSDK();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
isInstalledOnBrowser() {
|
|
59
|
-
var _a;
|
|
60
|
-
const metaMaskEip6963Provider = (_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns);
|
|
61
|
-
const isInstalled = Boolean(metaMaskEip6963Provider);
|
|
62
|
-
return isInstalled;
|
|
63
|
-
}
|
|
64
|
-
getSupportedNetworks() {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
return this.evmNetworks.map((network) => network.chainId.toString());
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
get metaMaskSDK() {
|
|
70
|
-
if (!_metaMaskSDK)
|
|
71
|
-
throw new Error('MetaMaskSDK not initialized');
|
|
72
|
-
return _metaMaskSDK;
|
|
73
|
-
}
|
|
74
|
-
set metaMaskSDK(metaMaskSDK) {
|
|
75
|
-
_metaMaskSDK = metaMaskSDK;
|
|
76
|
-
}
|
|
77
|
-
createMetaMaskSDK() {
|
|
78
|
-
const dappMetadata = {
|
|
79
|
-
iconUrl: this.appLogoUrl,
|
|
80
|
-
name: this.appName,
|
|
81
|
-
url: PlatformService.getOrigin(),
|
|
82
|
-
};
|
|
83
|
-
logger.debug('[MetaMaskConnector] createMetaMaskSDK - creating sdk', {
|
|
84
|
-
dappMetadata,
|
|
85
|
-
});
|
|
86
|
-
_metaMaskSDK = new MetaMaskSDK({
|
|
87
|
-
checkInstallationImmediately: true,
|
|
88
|
-
dappMetadata,
|
|
89
|
-
enableAnalytics: false,
|
|
90
|
-
extensionOnly: this.isInstalledOnBrowser(),
|
|
91
|
-
headless: true,
|
|
92
|
-
injectProvider: false,
|
|
93
|
-
openDeeplink: (url) => {
|
|
94
|
-
if (url.includes('://connect')) {
|
|
95
|
-
_metaMaskConnectUri = url;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
_metaMaskConnectUri = null;
|
|
99
|
-
}
|
|
100
|
-
PlatformService.openURL(url);
|
|
101
|
-
},
|
|
102
|
-
preferDesktop: !isMobile(),
|
|
103
|
-
readonlyRPCMap: getReadonlyRPCMap(this.evmNetworkRpcMap()),
|
|
104
|
-
useDeeplink: true,
|
|
105
|
-
});
|
|
106
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] createMetaMaskSDK - created sdk', { _metaMaskSDK });
|
|
107
|
-
}
|
|
108
|
-
endSession() {
|
|
109
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
-
eventTimeline.postEvent('disconnect');
|
|
111
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] endSession - terminating sdk');
|
|
112
|
-
/**
|
|
113
|
-
* The MetaMask SDK must be terminated and reinitialized on mobile
|
|
114
|
-
* to prevent deeplinks not working
|
|
115
|
-
*/
|
|
116
|
-
if (isMobile()) {
|
|
117
|
-
return this.metaMaskSDK.terminate().then(() => {
|
|
118
|
-
_metaMaskSDK = null;
|
|
119
|
-
_metaMaskConnectUri = null;
|
|
120
|
-
return this.createMetaMaskSDK();
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Just terminate the SDK on desktop
|
|
125
|
-
*/
|
|
126
|
-
return this.metaMaskSDK.terminate();
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
getAddress(opts) {
|
|
130
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - waiting for sdk init');
|
|
132
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
133
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - sdk init promise resolved');
|
|
134
|
-
// QR Code flow
|
|
135
|
-
const handleDisplayUri = (displayUri) => {
|
|
136
|
-
var _a;
|
|
137
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] handleDisplayUri', { displayUri });
|
|
138
|
-
if (!displayUri)
|
|
139
|
-
return;
|
|
140
|
-
setMetaMaskDisplayUri(displayUri);
|
|
141
|
-
(_a = opts === null || opts === void 0 ? void 0 : opts.onDisplayUri) === null || _a === void 0 ? void 0 : _a.call(opts, displayUri);
|
|
142
|
-
};
|
|
143
|
-
if (!isMobile() && Boolean(opts === null || opts === void 0 ? void 0 : opts.onDisplayUri)) {
|
|
144
|
-
this.metaMaskSDK.on('display_uri', handleDisplayUri);
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
// Deep link to MetaMask app in-app browser
|
|
148
|
-
if (this.shouldDeepLinkToMetaMaskInAppBrowser() &&
|
|
149
|
-
this.metadata.inAppBrowserUrl) {
|
|
150
|
-
const inAppBrowserCompiledTemplate = template(this.metadata.inAppBrowserUrl);
|
|
151
|
-
const { href } = PlatformService.getUrl();
|
|
152
|
-
const deepLink = inAppBrowserCompiledTemplate({
|
|
153
|
-
dappURI: href,
|
|
154
|
-
});
|
|
155
|
-
// Redirect to the in-app browser and append the current url
|
|
156
|
-
PlatformService.openURL(deepLink);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - getting initial connected accounts');
|
|
160
|
-
// Connect to MetaMask
|
|
161
|
-
const initialConnectedAccounts = yield this.getConnectedAccountsSafely();
|
|
162
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - got initial connected accounts', { initialConnectedAccounts });
|
|
163
|
-
if (initialConnectedAccounts.length) {
|
|
164
|
-
return this.parseAddress(initialConnectedAccounts[0]);
|
|
165
|
-
}
|
|
166
|
-
try {
|
|
167
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - connecting to metaMask');
|
|
168
|
-
const response = yield this.metaMaskSDK.connect();
|
|
169
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - connected to metaMask', { response });
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - error connecting to metaMask', { error });
|
|
173
|
-
/**
|
|
174
|
-
* In case of a getAddress call was already made and is pending
|
|
175
|
-
* and a new getAddress call is made after a endSession call, the
|
|
176
|
-
* MetaMask SDK will reject the original connect calls in the getAddress
|
|
177
|
-
* promise.
|
|
178
|
-
*
|
|
179
|
-
* In this case we want to cast the error to GetAddressCancelledError
|
|
180
|
-
* so the SDK knows the original getAddres call is cancelled and
|
|
181
|
-
* be clear to start the new getAddress flow
|
|
182
|
-
*/
|
|
183
|
-
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
184
|
-
throw new GetAddressCancelledError();
|
|
185
|
-
}
|
|
186
|
-
const isRequestPendingError = isPendingWalletRequestPermissionError(error);
|
|
187
|
-
if (!isRequestPendingError) {
|
|
188
|
-
throw MetaMaskError.fromError(error);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - error connection - waiting for connection');
|
|
192
|
-
// Get provider again after connect() attempt - it might be available now
|
|
193
|
-
const providerAfterConnect = this.getProvider();
|
|
194
|
-
if (providerAfterConnect) {
|
|
195
|
-
yield waitForConnection(providerAfterConnect);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - getting connected accounts');
|
|
200
|
-
const accounts = yield this.getConnectedAccounts();
|
|
201
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getAddress - got connected accounts', { accounts });
|
|
202
|
-
return accounts[0];
|
|
203
|
-
}
|
|
204
|
-
finally {
|
|
205
|
-
this.metaMaskSDK.off('display_uri', handleDisplayUri);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
getConnectedAccountsSafely() {
|
|
210
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
-
try {
|
|
212
|
-
const connectedAccounts = yield this.getConnectedAccounts();
|
|
213
|
-
return connectedAccounts;
|
|
214
|
-
}
|
|
215
|
-
catch (err) {
|
|
216
|
-
logger.error(err);
|
|
217
|
-
return [];
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
getConnectedAccounts() {
|
|
222
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
223
|
-
// Wait for for MetaMask SDK to initialize
|
|
224
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
225
|
-
const provider = this.getProvider();
|
|
226
|
-
if (!provider) {
|
|
227
|
-
return [];
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* The eth_accounts method can hang on mobile devices when
|
|
231
|
-
* the MetaMask SDK has not connected yet. So we use a retryable
|
|
232
|
-
* to ensure the timeout will be respected
|
|
233
|
-
*/
|
|
234
|
-
const accounts = yield retryableFn(() => provider.request({
|
|
235
|
-
method: 'eth_accounts',
|
|
236
|
-
params: [],
|
|
237
|
-
}), {
|
|
238
|
-
fallbackValue: [],
|
|
239
|
-
timeoutMs: 1000,
|
|
240
|
-
});
|
|
241
|
-
if (!(accounts === null || accounts === void 0 ? void 0 : accounts.length)) {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
return accounts.map(this.parseAddress);
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
signMessage(messageToSign) {
|
|
248
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
249
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - waiting for sdk init');
|
|
250
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
251
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - sdk init promise resolved');
|
|
252
|
-
/**
|
|
253
|
-
* Should wait for the window to be focused on mobile
|
|
254
|
-
* to account for the user moving between the MetaMaskApp
|
|
255
|
-
* and the browser
|
|
256
|
-
*/
|
|
257
|
-
const windowFocusPromiseForMobile = !this.isInAppBrowser && isMobile()
|
|
258
|
-
? waitForFocusWindowEvent()
|
|
259
|
-
: Promise.resolve();
|
|
260
|
-
const provider = this.getProvider();
|
|
261
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - got provider', { provider });
|
|
262
|
-
if (!provider) {
|
|
263
|
-
return undefined;
|
|
264
|
-
}
|
|
265
|
-
const [selectedAddress] = yield this.getConnectedAccounts();
|
|
266
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - got selected address', { selectedAddress });
|
|
267
|
-
if (!selectedAddress) {
|
|
268
|
-
return undefined;
|
|
269
|
-
}
|
|
270
|
-
const walletClient = this.getWalletClientForAddress(selectedAddress);
|
|
271
|
-
if (!walletClient)
|
|
272
|
-
return undefined;
|
|
273
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - will sign', { messageToSign });
|
|
274
|
-
const signature = yield walletClient.signMessage({
|
|
275
|
-
message: messageToSign,
|
|
276
|
-
});
|
|
277
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - will wait for window focus');
|
|
278
|
-
yield windowFocusPromiseForMobile;
|
|
279
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] signMessage - signed', { signature });
|
|
280
|
-
return signature;
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
chooseAccountsToConnect() {
|
|
284
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
285
|
-
return [];
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
getWalletClient(chainId) {
|
|
289
|
-
const provider = this.getProvider();
|
|
290
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getWalletClient - got provider', { provider });
|
|
291
|
-
if (!provider) {
|
|
292
|
-
return undefined;
|
|
293
|
-
}
|
|
294
|
-
const selectedAddress = provider.getSelectedAddress();
|
|
295
|
-
return this.getWalletClientForAddress(selectedAddress || undefined, chainId);
|
|
296
|
-
}
|
|
297
|
-
get rdns() {
|
|
298
|
-
const { rdns } = this.metadata;
|
|
299
|
-
if (!rdns) {
|
|
300
|
-
throw new Error('rdns not found in metadata');
|
|
301
|
-
}
|
|
302
|
-
return rdns;
|
|
303
|
-
}
|
|
304
|
-
setupEventListeners() {
|
|
305
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
307
|
-
const metaMaskProvider = this.getProvider();
|
|
308
|
-
if (!metaMaskProvider) {
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const { handleAccountChange, handleChainChange, handleDisconnect } = eventListenerHandlers(this);
|
|
312
|
-
const handleAccountsChangedFromMetaMask = (accounts) => {
|
|
313
|
-
/**
|
|
314
|
-
* MetaMask emits an account changed event when the wallet is disconnected
|
|
315
|
-
* so we ignore the accountsChanged event if the disconnect event was recent
|
|
316
|
-
*/
|
|
317
|
-
if (eventTimeline.isEventRecent('disconnect', 1000)) {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
321
|
-
// @ts-ignore
|
|
322
|
-
handleAccountChange(accounts);
|
|
323
|
-
};
|
|
324
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
325
|
-
// @ts-ignore
|
|
326
|
-
metaMaskProvider.on('accountsChanged', handleAccountsChangedFromMetaMask);
|
|
327
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
328
|
-
// @ts-ignore
|
|
329
|
-
metaMaskProvider.on('chainChanged', handleChainChange);
|
|
330
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
331
|
-
// @ts-ignore
|
|
332
|
-
metaMaskProvider.on('disconnect', handleDisconnect);
|
|
333
|
-
this.teardownEventListeners = () => {
|
|
334
|
-
metaMaskProvider.off('accountsChanged', handleAccountsChangedFromMetaMask);
|
|
335
|
-
metaMaskProvider.off('chainChanged', handleChainChange);
|
|
336
|
-
metaMaskProvider.off('disconnect', handleDisconnect);
|
|
337
|
-
};
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* This override is necessary to wait for the MetaMask SDK to initialize
|
|
342
|
-
* before calling the super method. Otherwise, the super method may fail
|
|
343
|
-
* to fetch the provider
|
|
344
|
-
*/
|
|
345
|
-
getNetwork() {
|
|
346
|
-
const _super = Object.create(null, {
|
|
347
|
-
getNetwork: { get: () => super.getNetwork }
|
|
348
|
-
});
|
|
349
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - waiting for sdk init');
|
|
351
|
-
yield this.metaMaskSDK.sdkInitPromise;
|
|
352
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - sdk init promise resolved');
|
|
353
|
-
const net = yield _super.getNetwork.call(this);
|
|
354
|
-
logger.logVerboseTroubleshootingMessage('[MetaMaskConnector] getNetwork - got network', { network: net });
|
|
355
|
-
return net;
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
// Utils
|
|
359
|
-
getProvider() {
|
|
360
|
-
var _a, _b;
|
|
361
|
-
try {
|
|
362
|
-
return ((_b = (_a = this.metaMaskSDK.getProvider()) !== null && _a !== void 0 ? _a : this.metaMaskSDK.getMobileProvider()) !== null && _b !== void 0 ? _b : undefined);
|
|
363
|
-
}
|
|
364
|
-
catch (_c) {
|
|
365
|
-
// If getMobileProvider throws (mobile provider not ready), return undefined
|
|
366
|
-
return undefined;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
evmNetworkByChainId(chainId) {
|
|
370
|
-
return this.evmNetworks.find((network) => network.chainId === chainId);
|
|
371
|
-
}
|
|
372
|
-
getWalletClientForAddress(address, chainId) {
|
|
373
|
-
var _a, _b;
|
|
374
|
-
const provider = this.getProvider();
|
|
375
|
-
if (!provider) {
|
|
376
|
-
return undefined;
|
|
377
|
-
}
|
|
378
|
-
const effectiveChainId = (_b = (_a = this.toInt(chainId)) !== null && _a !== void 0 ? _a : this.getCurrentChainId()) !== null && _b !== void 0 ? _b : '1';
|
|
379
|
-
const network = this.evmNetworkByChainId(effectiveChainId);
|
|
380
|
-
return createWalletClient({
|
|
381
|
-
account: address,
|
|
382
|
-
chain: network ? getOrMapViemChain(network) : this.getActiveChain(),
|
|
383
|
-
transport: custom(provider, this.providersConfig.httpTransportConfig),
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
toInt(chainId) {
|
|
387
|
-
if (!chainId)
|
|
388
|
-
return undefined;
|
|
389
|
-
try {
|
|
390
|
-
return parseInt(chainId);
|
|
391
|
-
}
|
|
392
|
-
catch (err) {
|
|
393
|
-
logger.debug(err);
|
|
394
|
-
return undefined;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
getCurrentChainId() {
|
|
398
|
-
const provider = this.getProvider();
|
|
399
|
-
if (!provider) {
|
|
400
|
-
return undefined;
|
|
401
|
-
}
|
|
402
|
-
const chainId = provider.getChainId();
|
|
403
|
-
if (isHex(chainId)) {
|
|
404
|
-
return parseInt(chainId);
|
|
405
|
-
}
|
|
406
|
-
return chainId;
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Checks if the current environment is the MetaMask in-app browser
|
|
410
|
-
* by checking if the MetaMask provider is installed in the window object
|
|
411
|
-
* on a mobile device
|
|
412
|
-
*/
|
|
413
|
-
getIsInAppBrowser() {
|
|
414
|
-
var _a, _b;
|
|
415
|
-
if (!isMobile())
|
|
416
|
-
return false;
|
|
417
|
-
const provider = ((_a = this.ethProviderHelper) === null || _a === void 0 ? void 0 : _a.eip6963ProviderLookup(this.rdns)) ||
|
|
418
|
-
((_b = this.ethProviderHelper) === null || _b === void 0 ? void 0 : _b.getInjectedProvider());
|
|
419
|
-
return Boolean(provider);
|
|
420
|
-
}
|
|
421
|
-
shouldDeepLinkToMetaMaskInAppBrowser() {
|
|
422
|
-
// Not in an in-app browser
|
|
423
|
-
if (this.isInAppBrowser) {
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
426
|
-
// Not a mobile device
|
|
427
|
-
if (!isMobile()) {
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
// SDK is configured to use the in-app browser
|
|
431
|
-
if (this.mobileExperience !== 'in-app-browser') {
|
|
432
|
-
return false;
|
|
433
|
-
}
|
|
434
|
-
// Wallet does not have an in-app browser link
|
|
435
|
-
if (!this.metadata.inAppBrowserUrl) {
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
// We don't want to deep link to the in-app browser when already in the in-app browser
|
|
439
|
-
if (navigator.userAgent.match(/metamaskmobile/i)) {
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
return true;
|
|
443
|
-
}
|
|
444
|
-
getConnectionUri() {
|
|
445
|
-
return _metaMaskDisplayUri !== null && _metaMaskDisplayUri !== void 0 ? _metaMaskDisplayUri : undefined;
|
|
446
|
-
}
|
|
447
|
-
retryDeeplinkConnection() {
|
|
448
|
-
if (_metaMaskConnectUri) {
|
|
449
|
-
PlatformService.openURL(_metaMaskConnectUri);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
// Utils
|
|
454
|
-
const getReadonlyRPCMap = (evmNetworkRpcMap) => Object.keys(evmNetworkRpcMap).reduce((acc, chainId) => (Object.assign(Object.assign({}, acc), { [toHex(parseInt(chainId))]: evmNetworkRpcMap[chainId] })), {});
|
|
455
|
-
/**
|
|
456
|
-
* Waits for the focus page event and await for an extra second
|
|
457
|
-
* This is necessary to ensure the verify call will succeed
|
|
458
|
-
*/
|
|
459
|
-
const waitForFocusWindowEvent = () => new Promise((resolve) => {
|
|
460
|
-
PlatformEventsService.once('appFocused', resolve);
|
|
461
|
-
}).then(() => new Promise((resolve) => setTimeout(resolve, 1000)));
|
|
462
|
-
|
|
463
|
-
export { MetaMaskConnector, eventTimeline, setMetaMaskDisplayUri };
|
|
@@ -1,11 +0,0 @@
|
|
|
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;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const isPendingWalletRequestPermissionError: (error: any) => any;
|
|
@@ -1,7 +0,0 @@
|
|
|
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 };
|
|
@@ -1,10 +0,0 @@
|
|
|
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;
|