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