@dynamic-labs/ethereum 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/package.json +9 -9
- package/src/coinbase/coinbase.cjs +24 -5
- package/src/coinbase/coinbase.d.ts +2 -1
- package/src/coinbase/coinbase.js +24 -5
- package/src/ethProviderHelper.cjs +6 -1
- package/src/ethProviderHelper.d.ts +2 -1
- package/src/ethProviderHelper.js +6 -1
- package/src/index.cjs +3 -9
- package/src/index.js +3 -9
- package/src/injected/InjectedWalletBase.cjs +2 -2
- package/src/injected/InjectedWalletBase.d.ts +1 -1
- package/src/injected/InjectedWalletBase.js +2 -2
- package/src/walletConnect/walletConnect.cjs +2 -136
- package/src/walletConnect/walletConnect.d.ts +3 -42
- package/src/walletConnect/walletConnect.js +3 -133
- package/src/walletConnect/walletConnectV2.cjs +97 -61
- package/src/walletConnect/walletConnectV2.d.ts +17 -14
- package/src/walletConnect/walletConnectV2.js +96 -60
- package/src/walletConnect/client/client.cjs +0 -201
- package/src/walletConnect/client/client.js +0 -187
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
2
|
-
import
|
|
2
|
+
import EthereumProvider from '@walletconnect/ethereum-provider';
|
|
3
3
|
import EventEmitter from 'eventemitter3';
|
|
4
4
|
import { createWalletClient, custom } from 'viem';
|
|
5
|
+
import { toAccount } from 'viem/accounts';
|
|
5
6
|
import { logger, performPlatformSpecificConnectionMethod, getDeepLink } from '@dynamic-labs/wallet-connector-core';
|
|
6
7
|
import { getWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
7
8
|
import { DynamicError, isMobile } from '@dynamic-labs/utils';
|
|
9
|
+
import { chainsMap } from '@dynamic-labs/viem-utils';
|
|
8
10
|
import { EthWalletConnector } from '../EthWalletConnector.js';
|
|
9
11
|
import { parseIntSafe } from '../utils/parseIntSafe.js';
|
|
10
12
|
|
|
@@ -26,6 +28,8 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
26
28
|
// When trying to switch network for MetaMask, the switch promise gets stuck
|
|
27
29
|
// if the switch got trigged once already, so we need to keep track of that
|
|
28
30
|
this._hasSwitchedNetwork = false;
|
|
31
|
+
this.sessionEventHandler = () => { };
|
|
32
|
+
this.sessionDeleteHandler = () => { };
|
|
29
33
|
this.name = opts.walletName;
|
|
30
34
|
this.projectId = opts.projectId;
|
|
31
35
|
this.deepLinkPreference = opts.deepLinkPreference || 'native';
|
|
@@ -51,7 +55,7 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
51
55
|
}
|
|
52
56
|
const reorderedChains = this.preferredChains.filter((chain) => allChains.includes(chain));
|
|
53
57
|
const remainingChains = allChains.filter((chain) => !this.preferredChains.includes(chain));
|
|
54
|
-
return [...reorderedChains, ...remainingChains];
|
|
58
|
+
return [...reorderedChains, ...remainingChains].map((chain) => Number(chain.split(':')[1]));
|
|
55
59
|
}
|
|
56
60
|
initConnection() {
|
|
57
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -60,44 +64,51 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
60
64
|
throw new DynamicError('No provider found (init connection)');
|
|
61
65
|
}
|
|
62
66
|
// this means there is already a connection in progress, so don't call connect again
|
|
63
|
-
if (provider === null || provider === void 0 ? void 0 : provider.uri) {
|
|
67
|
+
if (provider === null || provider === void 0 ? void 0 : provider.signer.uri) {
|
|
64
68
|
return;
|
|
65
69
|
}
|
|
66
|
-
|
|
67
|
-
eip155: {
|
|
68
|
-
chains: this.getMappedChainsByPreferredOrder(),
|
|
69
|
-
events: ['chainChanged', 'accountsChanged'],
|
|
70
|
-
methods: [
|
|
71
|
-
'eth_chainId',
|
|
72
|
-
'eth_signTypedData',
|
|
73
|
-
'eth_signTransaction',
|
|
74
|
-
'eth_sign',
|
|
75
|
-
'personal_sign',
|
|
76
|
-
'eth_sendTransaction',
|
|
77
|
-
'eth_signTypedData_v4',
|
|
78
|
-
'wallet_switchEthereumChain',
|
|
79
|
-
'wallet_addEthereumChain',
|
|
80
|
-
],
|
|
81
|
-
rpcMap: this.evmNetworkRpcMap(),
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
provider
|
|
85
|
-
.connect({
|
|
86
|
-
optionalNamespaces,
|
|
87
|
-
})
|
|
88
|
-
.catch((e) => {
|
|
70
|
+
provider.connect().catch((e) => {
|
|
89
71
|
logger.error(e);
|
|
90
72
|
ee.emit('walletconnect_connection_failed', e);
|
|
91
73
|
});
|
|
92
74
|
});
|
|
93
75
|
}
|
|
94
|
-
|
|
76
|
+
createProvider() {
|
|
95
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
-
|
|
97
|
-
|
|
78
|
+
return EthereumProvider.init({
|
|
79
|
+
events: ['chainChanged', 'accountsChanged'],
|
|
80
|
+
methods: [],
|
|
81
|
+
optionalChains: this.getMappedChainsByPreferredOrder(),
|
|
82
|
+
optionalMethods: [
|
|
83
|
+
'eth_chainId',
|
|
84
|
+
'eth_signTypedData',
|
|
85
|
+
'eth_signTransaction',
|
|
86
|
+
'eth_sign',
|
|
87
|
+
'personal_sign',
|
|
88
|
+
'eth_sendTransaction',
|
|
89
|
+
'eth_signTypedData_v4',
|
|
90
|
+
'wallet_switchEthereumChain',
|
|
91
|
+
'wallet_addEthereumChain',
|
|
92
|
+
],
|
|
98
93
|
projectId: this.projectId,
|
|
94
|
+
rpcMap: this.evmNetworkRpcMap(),
|
|
95
|
+
showQrModal: false,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
getWalletClientFromInitializedProvider() {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
const walletConnect = this.createProvider();
|
|
102
|
+
const walletClient = createWalletClient({
|
|
103
|
+
account: this.activeAccount ? toAccount(this.activeAccount) : undefined,
|
|
104
|
+
transport: custom(yield walletConnect),
|
|
99
105
|
});
|
|
100
|
-
|
|
106
|
+
return walletClient;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
createInitProviderPromise() {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
WalletConnectV2.provider = yield this.createProvider();
|
|
101
112
|
this.teardownEventListeners();
|
|
102
113
|
this.setupEventListeners();
|
|
103
114
|
});
|
|
@@ -173,7 +184,7 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
173
184
|
if (!WalletConnectV2.provider) {
|
|
174
185
|
return;
|
|
175
186
|
}
|
|
176
|
-
|
|
187
|
+
this.sessionEventHandler = ({ params, }) => {
|
|
177
188
|
logger.debug('session_event was called', { params });
|
|
178
189
|
if (!params || !params.event) {
|
|
179
190
|
logger.debug('session_event was called without params or params.event');
|
|
@@ -182,12 +193,17 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
182
193
|
const { name, data } = params.event;
|
|
183
194
|
if (name === 'chainChanged') {
|
|
184
195
|
const chainId = parseIntSafe(data);
|
|
196
|
+
if (chainId === this.currentChainId) {
|
|
197
|
+
logger.debug(`ignoring chainChanged event with same chain id as current chain id: ${chainId}`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
185
200
|
if (chainId === undefined) {
|
|
186
201
|
logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
|
|
187
202
|
return;
|
|
188
203
|
}
|
|
189
204
|
this.currentChainId = chainId;
|
|
190
205
|
this.emit('chainChange', { chain: String(chainId) });
|
|
206
|
+
this.hasSwitchedNetwork = true;
|
|
191
207
|
// When a user switches network from their wallet, we need the provider to change network
|
|
192
208
|
// such that any future calls to `getNetwork` will return the correct network
|
|
193
209
|
this.switchNetwork({ networkChainId: chainId });
|
|
@@ -201,24 +217,28 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
201
217
|
const account = data[0].split(':')[2];
|
|
202
218
|
this.setActiveAccount(account);
|
|
203
219
|
}
|
|
204
|
-
}
|
|
205
|
-
WalletConnectV2.provider.
|
|
220
|
+
};
|
|
221
|
+
WalletConnectV2.provider.on('session_event', this.sessionEventHandler);
|
|
222
|
+
this.sessionDeleteHandler = () => __awaiter(this, void 0, void 0, function* () {
|
|
206
223
|
this.endSession();
|
|
207
224
|
this.emit('disconnect');
|
|
208
|
-
})
|
|
225
|
+
});
|
|
226
|
+
WalletConnectV2.provider.on('session_delete', this.sessionDeleteHandler);
|
|
209
227
|
}
|
|
210
228
|
teardownEventListeners() {
|
|
211
229
|
if (!WalletConnectV2.provider) {
|
|
212
230
|
return;
|
|
213
231
|
}
|
|
214
|
-
WalletConnectV2.provider.
|
|
215
|
-
WalletConnectV2.provider.
|
|
232
|
+
WalletConnectV2.provider.off('session_event', this.sessionEventHandler);
|
|
233
|
+
WalletConnectV2.provider.off('session_delete', this.sessionDeleteHandler);
|
|
216
234
|
}
|
|
217
|
-
getWalletClient() {
|
|
235
|
+
getWalletClient(chainId) {
|
|
218
236
|
if (!WalletConnectV2.provider) {
|
|
219
237
|
return;
|
|
220
238
|
}
|
|
221
239
|
return createWalletClient({
|
|
240
|
+
account: this.activeAccount ? toAccount(this.activeAccount) : undefined,
|
|
241
|
+
chain: chainsMap[chainId !== null && chainId !== void 0 ? chainId : String(this.currentChainId)],
|
|
222
242
|
transport: custom(WalletConnectV2.provider),
|
|
223
243
|
});
|
|
224
244
|
}
|
|
@@ -228,7 +248,7 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
228
248
|
if (this.activeAccount) {
|
|
229
249
|
return this.activeAccount;
|
|
230
250
|
}
|
|
231
|
-
if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
|
|
251
|
+
if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.signer.uri)) {
|
|
232
252
|
logger.debug('No WC2 provider found, re-initializing...');
|
|
233
253
|
yield this.endSession();
|
|
234
254
|
yield this.init();
|
|
@@ -238,13 +258,13 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
238
258
|
// finish setting up the connection URI and making it available
|
|
239
259
|
// on the provider
|
|
240
260
|
yield new Promise((resolve) => setTimeout(resolve, 1000));
|
|
241
|
-
if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
|
|
261
|
+
if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.signer.uri)) {
|
|
242
262
|
logger.debug('No WC2 provider found, escaping and throwing error');
|
|
243
263
|
throw new DynamicError('No provider found');
|
|
244
264
|
}
|
|
245
265
|
}
|
|
246
266
|
const metadata = getWalletBookWallet(this.walletBook, this.key);
|
|
247
|
-
performPlatformSpecificConnectionMethod(WalletConnectV2.provider.uri, metadata, {
|
|
267
|
+
performPlatformSpecificConnectionMethod(WalletConnectV2.provider.signer.uri, metadata, {
|
|
248
268
|
onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
|
|
249
269
|
onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
|
|
250
270
|
}, this.deepLinkPreference);
|
|
@@ -257,7 +277,7 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
257
277
|
const error = new DynamicError('Connection rejected. Please try again.');
|
|
258
278
|
error.code = 'connection_rejected';
|
|
259
279
|
if (WalletConnectV2.provider) {
|
|
260
|
-
WalletConnectV2.provider.uri = undefined;
|
|
280
|
+
WalletConnectV2.provider.signer.uri = undefined;
|
|
261
281
|
// this is needed for mobile to work when using universal links.
|
|
262
282
|
// if the user cancels the connection, we need to re-initialize the provider
|
|
263
283
|
// so that the async work is done ahead of time, before the user tries to connect again,
|
|
@@ -266,13 +286,19 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
266
286
|
}
|
|
267
287
|
reject(error);
|
|
268
288
|
});
|
|
269
|
-
WalletConnectV2.provider.on('connect', (
|
|
289
|
+
WalletConnectV2.provider.on('connect', () => {
|
|
290
|
+
var _a;
|
|
291
|
+
const session = (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session;
|
|
270
292
|
if (!session) {
|
|
271
293
|
reject(new DynamicError('No session found'));
|
|
294
|
+
return;
|
|
272
295
|
}
|
|
273
296
|
this.setSession(session);
|
|
274
297
|
this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
|
|
275
|
-
|
|
298
|
+
this.getNetwork().then((chainId) => {
|
|
299
|
+
this.currentChainId = chainId;
|
|
300
|
+
resolve(this.activeAccount);
|
|
301
|
+
});
|
|
276
302
|
});
|
|
277
303
|
});
|
|
278
304
|
});
|
|
@@ -290,10 +316,12 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
290
316
|
*/
|
|
291
317
|
waitForSignMessage(signMessageFn, messageToSign) {
|
|
292
318
|
return __awaiter(this, void 0, void 0, function* () {
|
|
293
|
-
const raceConditionPromise = new Promise((resolve) => {
|
|
319
|
+
const raceConditionPromise = new Promise((resolve, reject) => {
|
|
294
320
|
// Create listener for chain change event
|
|
295
321
|
this.on('chainChange', () => resolve({ success: false }));
|
|
296
|
-
signMessageFn(messageToSign)
|
|
322
|
+
signMessageFn(messageToSign)
|
|
323
|
+
.then((result) => resolve({ signedMessage: result, success: true }))
|
|
324
|
+
.catch(reject);
|
|
297
325
|
});
|
|
298
326
|
const signedMessageResult = yield raceConditionPromise;
|
|
299
327
|
if (signedMessageResult.success === false) {
|
|
@@ -312,7 +340,7 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
312
340
|
metadata,
|
|
313
341
|
mode: 'regular',
|
|
314
342
|
preference: this.deepLinkPreference,
|
|
315
|
-
uri: (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri,
|
|
343
|
+
uri: (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.signer.uri,
|
|
316
344
|
});
|
|
317
345
|
if (!deepLink) {
|
|
318
346
|
return;
|
|
@@ -326,10 +354,6 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
326
354
|
if (!this.session) {
|
|
327
355
|
throw new DynamicError('no session');
|
|
328
356
|
}
|
|
329
|
-
const web3Provider = this.getWalletClient();
|
|
330
|
-
if (!web3Provider) {
|
|
331
|
-
throw new DynamicError('No WalletConnect provider found to handle signing');
|
|
332
|
-
}
|
|
333
357
|
const deepLink = this.getDeepLink();
|
|
334
358
|
if (isMobile() && deepLink) {
|
|
335
359
|
window.location.href = deepLink;
|
|
@@ -339,7 +363,8 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
339
363
|
if (!activeAccount) {
|
|
340
364
|
return;
|
|
341
365
|
}
|
|
342
|
-
|
|
366
|
+
const walletClient = yield this.getWalletClientFromInitializedProvider();
|
|
367
|
+
return walletClient.signMessage({
|
|
343
368
|
account: activeAccount,
|
|
344
369
|
message: messageToSign,
|
|
345
370
|
});
|
|
@@ -398,11 +423,17 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
398
423
|
return _super.getNetwork.call(this);
|
|
399
424
|
});
|
|
400
425
|
}
|
|
401
|
-
providerSwitchNetwork({ network,
|
|
426
|
+
providerSwitchNetwork({ network, }) {
|
|
402
427
|
const _super = Object.create(null, {
|
|
403
428
|
providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
|
|
404
429
|
});
|
|
405
430
|
return __awaiter(this, void 0, void 0, function* () {
|
|
431
|
+
const supportedNetworks = yield this.getSupportedNetworks();
|
|
432
|
+
if (!(supportedNetworks === null || supportedNetworks === void 0 ? void 0 : supportedNetworks.includes(network.chainId.toString()))) {
|
|
433
|
+
const error = new DynamicError('Network switching is not available at this time. The user should manually switch network in their wallet');
|
|
434
|
+
error.code = 'network_switching_only_available_in_wallet';
|
|
435
|
+
throw error;
|
|
436
|
+
}
|
|
406
437
|
const currentNetworkId = yield this.getNetwork();
|
|
407
438
|
if (currentNetworkId && currentNetworkId === network.chainId) {
|
|
408
439
|
return;
|
|
@@ -413,10 +444,14 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
413
444
|
if (!this.supportsNetworkSwitching()) {
|
|
414
445
|
throw new DynamicError('Network switching not supported');
|
|
415
446
|
}
|
|
416
|
-
|
|
417
|
-
|
|
447
|
+
const walletClient = yield this.getWalletClientFromInitializedProvider();
|
|
448
|
+
if (this.isMetaMask()) {
|
|
449
|
+
const deepLink = this.getDeepLink();
|
|
450
|
+
if (deepLink) {
|
|
451
|
+
window.location.href = deepLink;
|
|
452
|
+
}
|
|
418
453
|
}
|
|
419
|
-
yield _super.providerSwitchNetwork.call(this, { network, provider });
|
|
454
|
+
yield _super.providerSwitchNetwork.call(this, { network, provider: walletClient });
|
|
420
455
|
this.currentChainId = network.chainId;
|
|
421
456
|
this.hasSwitchedNetwork = true;
|
|
422
457
|
this.emit('chainChange', { chain: String(network.chainId) });
|
|
@@ -442,13 +477,14 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
442
477
|
getSupportedNetworks() {
|
|
443
478
|
var _a;
|
|
444
479
|
return __awaiter(this, void 0, void 0, function* () {
|
|
445
|
-
// MM allows you to switch to any network the first time, even if it's not enabled in MM
|
|
446
|
-
// so we should consider all networks as supported if network switching hasn't been triggered yet
|
|
447
|
-
if (this.isMetaMask() && !this.hasSwitchedNetwork) {
|
|
448
|
-
return this.evmNetworks.map((network) => network.chainId.toString());
|
|
449
|
-
}
|
|
450
480
|
yield this.initProvider();
|
|
451
481
|
this.refreshSession();
|
|
482
|
+
if (this.isMetaMask()) {
|
|
483
|
+
if (this.hasSwitchedNetwork) {
|
|
484
|
+
return [String(this.currentChainId)];
|
|
485
|
+
}
|
|
486
|
+
return this.evmNetworks.map((network) => network.chainId.toString());
|
|
487
|
+
}
|
|
452
488
|
if (!this.session) {
|
|
453
489
|
return [];
|
|
454
490
|
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var _tslib = require('../../../_virtual/_tslib.cjs');
|
|
6
|
-
var Client = require('@walletconnect/client');
|
|
7
|
-
var viem = require('viem');
|
|
8
|
-
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
9
|
-
var utils = require('@dynamic-labs/utils');
|
|
10
|
-
|
|
11
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
-
|
|
13
|
-
var Client__default = /*#__PURE__*/_interopDefaultLegacy(Client);
|
|
14
|
-
|
|
15
|
-
const initClient = (key, bridge, settings) => {
|
|
16
|
-
const storageId = `walletconnect-${key}`;
|
|
17
|
-
const session = localStorage.getItem(storageId);
|
|
18
|
-
const clientArgs = session
|
|
19
|
-
? { session: JSON.parse(session), storageId }
|
|
20
|
-
: { bridge, storageId };
|
|
21
|
-
return new Client__default["default"](Object.assign(Object.assign({}, clientArgs), settings));
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Attach event handlers to WalletConnect events.
|
|
25
|
-
*/
|
|
26
|
-
const setupWalletConnectEventListeners = (walletConnector, client) => {
|
|
27
|
-
if (!client) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
let prevAccount;
|
|
31
|
-
let prevChain;
|
|
32
|
-
if (client.connected) {
|
|
33
|
-
// eslint-disable-next-line prefer-destructuring
|
|
34
|
-
prevAccount = client.accounts[0];
|
|
35
|
-
prevChain = client.chainId;
|
|
36
|
-
}
|
|
37
|
-
client.on('disconnect', () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
-
walletConnector.emit('disconnect');
|
|
39
|
-
}));
|
|
40
|
-
client.on('session_update', (_, payload) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
-
// eslint-disable-next-line prefer-destructuring
|
|
42
|
-
const { accounts, chainId } = payload.params[0];
|
|
43
|
-
const didAccountChange = !walletConnectorCore.isSameAddress(prevAccount || '', accounts[0], 'eip155');
|
|
44
|
-
const didChainChange = prevChain !== chainId;
|
|
45
|
-
// eslint-disable-next-line prefer-destructuring
|
|
46
|
-
prevAccount = accounts[0];
|
|
47
|
-
prevChain = chainId;
|
|
48
|
-
if (didAccountChange) {
|
|
49
|
-
walletConnector.emit('accountChange', { accounts });
|
|
50
|
-
}
|
|
51
|
-
if (didChainChange) {
|
|
52
|
-
walletConnector.emit('chainChange', { chain: String(chainId) });
|
|
53
|
-
}
|
|
54
|
-
}));
|
|
55
|
-
};
|
|
56
|
-
const teardownWalletConnectEventListeners = (client) => {
|
|
57
|
-
client.off('disconnect');
|
|
58
|
-
client.off('session_update');
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Initialize a client from a stored session and terminate the connection.
|
|
62
|
-
*/
|
|
63
|
-
const killWalletConnectSession = (client) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
-
try {
|
|
65
|
-
if (client === null || client === void 0 ? void 0 : client.connected) {
|
|
66
|
-
yield client.killSession();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (e) {
|
|
70
|
-
walletConnectorCore.logger.debug(e);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
const createSession = (client) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
client.on('connect', (error, payload) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
-
if (error)
|
|
77
|
-
throw error;
|
|
78
|
-
resolve(payload);
|
|
79
|
-
}));
|
|
80
|
-
client.on('disconnect', (error, payload) => {
|
|
81
|
-
reject(error || payload.params[0].message);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
const fetchWalletConnectEVMPublicAddress = (metadata, wcClient, deepLinkPreference, opts) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
-
var _a;
|
|
87
|
-
if (wcClient.connected) {
|
|
88
|
-
const [accountPublicAddress] = wcClient.accounts;
|
|
89
|
-
return accountPublicAddress;
|
|
90
|
-
}
|
|
91
|
-
// createSession will trigger the QR code...
|
|
92
|
-
yield wcClient.createSession();
|
|
93
|
-
walletConnectorCore.performPlatformSpecificConnectionMethod(wcClient.uri, metadata, {
|
|
94
|
-
onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
|
|
95
|
-
onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
|
|
96
|
-
}, deepLinkPreference);
|
|
97
|
-
const payload = yield createSession(wcClient);
|
|
98
|
-
(_a = opts === null || opts === void 0 ? void 0 : opts.onConnect) === null || _a === void 0 ? void 0 : _a.call(opts, payload);
|
|
99
|
-
const [accountPublicAddress] = payload.params[0].accounts;
|
|
100
|
-
return accountPublicAddress;
|
|
101
|
-
});
|
|
102
|
-
const signWalletConnectPersonalMessage = (messageToSign, metadata, client, deepLinkPreference, rpcProvider) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
-
var _b, _c;
|
|
104
|
-
const isCryptoWallet = ((_b = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _b === void 0 ? void 0 : _b.name) === 'Crypto.com | DeFi Wallet' ||
|
|
105
|
-
((_c = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _c === void 0 ? void 0 : _c.name) === 'DeFi Wallet';
|
|
106
|
-
if (!client || !client.connected) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const [accountPublicAddress] = client.accounts;
|
|
110
|
-
if (utils.isMobile()) {
|
|
111
|
-
const deepLink = walletConnectorCore.getDeepLink({
|
|
112
|
-
metadata,
|
|
113
|
-
mode: 'regular',
|
|
114
|
-
preference: deepLinkPreference,
|
|
115
|
-
uri: client.uri,
|
|
116
|
-
});
|
|
117
|
-
window.location.href = deepLink;
|
|
118
|
-
}
|
|
119
|
-
try {
|
|
120
|
-
// This delay is required for Crypto.com DeFi wallet, when there is no delay the app
|
|
121
|
-
// will not open the pop-up to sign. That seems to be a limitation in the standalone client
|
|
122
|
-
// so the delay is required to allow the users to sign the message
|
|
123
|
-
if (isCryptoWallet && utils.isMobile()) {
|
|
124
|
-
yield sleep(4000);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
// The delay of 1 second is necessary for some of the wallets to open the sign UI in the
|
|
128
|
-
// correct order, without this some wallets like Trust or OKX will no open properly,
|
|
129
|
-
// and not allowing the user to sign the message
|
|
130
|
-
yield sleep(1000);
|
|
131
|
-
}
|
|
132
|
-
const signature = yield client.signPersonalMessage([
|
|
133
|
-
messageToSign,
|
|
134
|
-
accountPublicAddress,
|
|
135
|
-
]);
|
|
136
|
-
yield waitForSafeTransactionOrTimeout(accountPublicAddress, signature, messageToSign, client, rpcProvider);
|
|
137
|
-
return signature;
|
|
138
|
-
}
|
|
139
|
-
catch (e) {
|
|
140
|
-
walletConnectorCore.logger.debug(e);
|
|
141
|
-
throw e;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
145
|
-
// Successful value as defined by the EIP
|
|
146
|
-
// https://eips.ethereum.org/EIPS/eip-1271#specification
|
|
147
|
-
const MAGIC_VALUE = '0x1626ba7e';
|
|
148
|
-
const IS_VALID_SIGNATURE_ABI = [
|
|
149
|
-
'function isValidSignature(bytes32 _message, bytes _signature) public view returns (bytes4)',
|
|
150
|
-
];
|
|
151
|
-
const waitForSafeTransactionOrTimeout = (accountPublicAddress, signature, messageToSign, client, rpcProvider) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
-
var _d;
|
|
153
|
-
if (signature === '0x' &&
|
|
154
|
-
// this is what wallet connect client returns there's no `safe` or `Safe`
|
|
155
|
-
// exact string anywhere, so this seems like the best proxy
|
|
156
|
-
((_d = client.peerMeta) === null || _d === void 0 ? void 0 : _d.name) === 'WalletConnect Safe App') {
|
|
157
|
-
if (!rpcProvider) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
const safeTransactionPromise = waitForSafeTransaction(accountPublicAddress, signature, messageToSign, yield rpcProvider());
|
|
161
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
162
|
-
setTimeout(resolve, 120000);
|
|
163
|
-
});
|
|
164
|
-
yield Promise.race([safeTransactionPromise, timeoutPromise]);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
// this is a hack for safe
|
|
168
|
-
// before sending the signature downstream, we need to make sure
|
|
169
|
-
// the transaction is recorded first on the blockchain
|
|
170
|
-
// redcoast verify WILL fail if it attempts to verify the signature
|
|
171
|
-
// that has not yet been properly processed!
|
|
172
|
-
const waitForSafeTransaction = (accountPublicAddress, signature, messageToSign, rpcProvider) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
173
|
-
// wait for safe wallet to finish txn on the blockchain contract
|
|
174
|
-
for (let i = 0; i < 120; i++) {
|
|
175
|
-
try {
|
|
176
|
-
// this will result in an exception if the transaction is still not ready
|
|
177
|
-
// we need to catch it below
|
|
178
|
-
const result = yield (rpcProvider === null || rpcProvider === void 0 ? void 0 : rpcProvider.readContract({
|
|
179
|
-
abi: IS_VALID_SIGNATURE_ABI,
|
|
180
|
-
address: accountPublicAddress,
|
|
181
|
-
args: [viem.hashMessage(messageToSign), signature],
|
|
182
|
-
functionName: 'isValidSignature',
|
|
183
|
-
}));
|
|
184
|
-
if (result === MAGIC_VALUE)
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
catch (err) {
|
|
188
|
-
walletConnectorCore.logger.info('Safe transaction cannot be validated yet. Retrying.');
|
|
189
|
-
}
|
|
190
|
-
// try again after 2 seconds
|
|
191
|
-
yield sleep(2000);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
exports.createSession = createSession;
|
|
196
|
-
exports.fetchWalletConnectEVMPublicAddress = fetchWalletConnectEVMPublicAddress;
|
|
197
|
-
exports.initClient = initClient;
|
|
198
|
-
exports.killWalletConnectSession = killWalletConnectSession;
|
|
199
|
-
exports.setupWalletConnectEventListeners = setupWalletConnectEventListeners;
|
|
200
|
-
exports.signWalletConnectPersonalMessage = signWalletConnectPersonalMessage;
|
|
201
|
-
exports.teardownWalletConnectEventListeners = teardownWalletConnectEventListeners;
|