@dynamic-labs/ethereum 0.19.0-alpha.8 → 0.19.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +321 -0
  2. package/package.json +13 -10
  3. package/src/EthWalletConnector.cjs +189 -193
  4. package/src/EthWalletConnector.d.ts +298 -41
  5. package/src/EthWalletConnector.js +190 -194
  6. package/src/coinbase/client/client.cjs +78 -0
  7. package/src/coinbase/client/client.d.ts +6 -0
  8. package/src/coinbase/client/client.js +71 -0
  9. package/src/coinbase/client/index.d.ts +2 -0
  10. package/src/coinbase/client/types.d.ts +14 -0
  11. package/src/coinbase/coinbase.cjs +71 -0
  12. package/src/coinbase/coinbase.d.ts +535 -0
  13. package/src/coinbase/coinbase.js +67 -0
  14. package/src/coinbase/index.d.ts +3 -0
  15. package/src/constants.d.ts +1 -1
  16. package/src/ethProviderHelper.cjs +132 -208
  17. package/src/ethProviderHelper.d.ts +28 -36
  18. package/src/ethProviderHelper.js +133 -209
  19. package/src/index.cjs +30 -26
  20. package/src/index.d.ts +9 -8
  21. package/src/index.js +25 -20
  22. package/src/injected/BloctoInjected.cjs +6 -6
  23. package/src/injected/BloctoInjected.d.ts +4 -4
  24. package/src/injected/BloctoInjected.js +6 -6
  25. package/src/injected/BraveEvm.cjs +6 -6
  26. package/src/injected/BraveEvm.d.ts +4 -4
  27. package/src/injected/BraveEvm.js +6 -6
  28. package/src/injected/Dawn.cjs +6 -6
  29. package/src/injected/Dawn.d.ts +4 -4
  30. package/src/injected/Dawn.js +6 -6
  31. package/src/injected/ExodusEvm.cjs +8 -8
  32. package/src/injected/ExodusEvm.d.ts +5 -5
  33. package/src/injected/ExodusEvm.js +7 -7
  34. package/src/injected/Frame.cjs +6 -6
  35. package/src/injected/Frame.d.ts +4 -4
  36. package/src/injected/Frame.js +6 -6
  37. package/src/injected/GameStop.cjs +6 -6
  38. package/src/injected/GameStop.d.ts +4 -4
  39. package/src/injected/GameStop.js +6 -6
  40. package/src/injected/InjectedWalletBase.cjs +86 -65
  41. package/src/injected/InjectedWalletBase.d.ts +29 -24
  42. package/src/injected/InjectedWalletBase.js +86 -65
  43. package/src/injected/LegacyInjectedWalletBase.cjs +83 -0
  44. package/src/injected/LegacyInjectedWalletBase.d.ts +24 -0
  45. package/src/injected/LegacyInjectedWalletBase.js +81 -0
  46. package/src/injected/Opera.cjs +6 -6
  47. package/src/injected/Opera.d.ts +4 -4
  48. package/src/injected/Opera.js +6 -6
  49. package/src/injected/PhantomEvm.cjs +28 -28
  50. package/src/injected/PhantomEvm.d.ts +5 -5
  51. package/src/injected/PhantomEvm.js +28 -28
  52. package/src/injected/Rabby.cjs +8 -8
  53. package/src/injected/Rabby.d.ts +5 -5
  54. package/src/injected/Rabby.js +7 -7
  55. package/src/injected/Superb.cjs +6 -6
  56. package/src/injected/Superb.d.ts +4 -4
  57. package/src/injected/Superb.js +6 -6
  58. package/src/injected/Trust.cjs +8 -8
  59. package/src/injected/Trust.d.ts +5 -5
  60. package/src/injected/Trust.js +7 -7
  61. package/src/injected/Zerion.cjs +8 -8
  62. package/src/injected/Zerion.d.ts +5 -5
  63. package/src/injected/Zerion.js +7 -7
  64. package/src/injected/fetchInjectedWalletConnectors.cjs +33 -0
  65. package/src/injected/fetchInjectedWalletConnectors.d.ts +6 -0
  66. package/src/injected/fetchInjectedWalletConnectors.js +29 -0
  67. package/src/injected/index.d.ts +13 -16
  68. package/src/injected/legacyInjectedWallets.cjs +48 -0
  69. package/src/injected/legacyInjectedWallets.d.ts +3 -0
  70. package/src/injected/legacyInjectedWallets.js +43 -0
  71. package/src/legacyEthProviderHelper.cjs +187 -0
  72. package/src/legacyEthProviderHelper.d.ts +34 -0
  73. package/src/legacyEthProviderHelper.js +183 -0
  74. package/src/polyfills.cjs +11 -11
  75. package/src/polyfills.d.ts +1 -1
  76. package/src/polyfills.js +11 -11
  77. package/src/types.d.ts +37 -24
  78. package/src/utils/eventListenerHandlers.cjs +34 -0
  79. package/src/utils/eventListenerHandlers.d.ts +8 -0
  80. package/src/utils/eventListenerHandlers.js +30 -0
  81. package/src/utils/findEvmNetwork.cjs +13 -13
  82. package/src/utils/findEvmNetwork.d.ts +6 -6
  83. package/src/utils/findEvmNetwork.js +13 -13
  84. package/src/utils/isString.d.ts +1 -1
  85. package/src/utils/isUnsupportedProviderError/index.d.ts +1 -1
  86. package/src/utils/isUnsupportedProviderError/isUnsupportedProviderError.cjs +6 -6
  87. package/src/utils/isUnsupportedProviderError/isUnsupportedProviderError.d.ts +6 -6
  88. package/src/utils/isUnsupportedProviderError/isUnsupportedProviderError.js +6 -6
  89. package/src/utils/last.d.ts +1 -1
  90. package/src/utils/parseIntSafe.cjs +13 -13
  91. package/src/utils/parseIntSafe.d.ts +1 -1
  92. package/src/utils/parseIntSafe.js +13 -13
  93. package/src/walletConnect/client/client.cjs +179 -175
  94. package/src/walletConnect/client/client.d.ts +17 -17
  95. package/src/walletConnect/client/client.js +179 -175
  96. package/src/walletConnect/client/index.d.ts +1 -1
  97. package/src/walletConnect/client/types.d.ts +4 -4
  98. package/src/walletConnect/fetchWalletConnectWallets.cjs +37 -52
  99. package/src/walletConnect/fetchWalletConnectWallets.d.ts +9 -10
  100. package/src/walletConnect/fetchWalletConnectWallets.js +38 -52
  101. package/src/walletConnect/index.d.ts +3 -3
  102. package/src/walletConnect/walletConnect.cjs +131 -129
  103. package/src/walletConnect/walletConnect.d.ts +52 -52
  104. package/src/walletConnect/walletConnect.js +131 -129
  105. package/src/walletConnect/walletConnectV2.cjs +419 -385
  106. package/src/walletConnect/walletConnectV2.d.ts +326 -64
  107. package/src/walletConnect/walletConnectV2.js +420 -386
  108. package/src/injected/MetaMask.cjs +0 -15
  109. package/src/injected/MetaMask.d.ts +0 -5
  110. package/src/injected/MetaMask.js +0 -11
  111. package/src/injected/OKX.cjs +0 -15
  112. package/src/injected/OKX.d.ts +0 -5
  113. package/src/injected/OKX.js +0 -11
  114. package/src/injected/UnknownInjectedWallet.cjs +0 -14
  115. package/src/injected/UnknownInjectedWallet.d.ts +0 -4
  116. package/src/injected/UnknownInjectedWallet.js +0 -10
  117. package/src/injected/index.cjs +0 -53
  118. package/src/injected/index.js +0 -49
@@ -1,397 +1,431 @@
1
1
  import { __awaiter } from '../../_virtual/_tslib.js';
2
2
  import Provider from '@walletconnect/universal-provider';
3
- import { ethers } from 'ethers';
4
3
  import EventEmitter from 'eventemitter3';
5
- import { logger, performPlatformSpecificConnectionMethod, getDeepLink, utf8ToHex } from '@dynamic-labs/wallet-connector-core';
4
+ import { createWalletClient, custom } from 'viem';
5
+ import { logger, performPlatformSpecificConnectionMethod, getDeepLink } from '@dynamic-labs/wallet-connector-core';
6
6
  import { getWalletBookWallet } from '@dynamic-labs/wallet-book';
7
7
  import { DynamicError, isMobile } from '@dynamic-labs/utils';
8
8
  import { EthWalletConnector } from '../EthWalletConnector.js';
9
9
  import { parseIntSafe } from '../utils/parseIntSafe.js';
10
10
 
11
- const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
12
- const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
13
- const ee = new EventEmitter();
14
- class WalletConnectV2 extends EthWalletConnector {
15
- constructor(opts) {
16
- super(opts);
17
- this.supportedChains = ['EVM', 'ETH'];
18
- this.connectedChain = 'EVM';
19
- this.isInitialized = false;
20
- this.canConnectViaQrCode = true;
21
- this.isWalletConnect = true;
22
- this.name = opts.walletName;
23
- this.projectId = opts.projectId;
24
- this.deepLinkPreference = opts.deepLinkPreference || 'native';
25
- }
26
- getDefaultChainId() {
27
- var _a, _b;
28
- const etheriumMainnetNetwork = (_a = this.evmNetworks) === null || _a === void 0 ? void 0 : _a.find((network) => network.chainId === 1);
29
- if (!etheriumMainnetNetwork && ((_b = this.evmNetworks) === null || _b === void 0 ? void 0 : _b.length)) {
30
- return this.evmNetworks[0].chainId;
31
- }
32
- return 1;
33
- }
34
- initConnection() {
35
- return __awaiter(this, void 0, void 0, function* () {
36
- const { provider } = WalletConnectV2;
37
- if (!provider) {
38
- throw new DynamicError('No provider found (init connection)');
39
- }
40
- // this means there is already a connection in progress, so don't call connect again
41
- if (provider === null || provider === void 0 ? void 0 : provider.uri) {
42
- return;
43
- }
44
- const defaultChain = this.getDefaultChainId();
45
- provider
46
- .connect({
47
- namespaces: {
48
- eip155: {
49
- chains: [`eip155:${defaultChain}`],
50
- events: ['chainChanged', 'accountsChanged'],
51
- methods: ['personal_sign', 'eth_sendTransaction'],
52
- rpcMap: this.evmNetworkRpcMap(),
53
- },
54
- },
55
- optionalNamespaces: {
56
- eip155: {
57
- chains: this.evmNetworks
58
- // Filters out mainnet which is required and palm that crashes Trust Wallet
59
- .filter((network) => network.chainId !== 11297108109 &&
60
- network.chainId !== defaultChain)
61
- .map((network) => `eip155:${network.chainId}`),
62
- events: [],
63
- methods: [
64
- 'eth_signTypedData',
65
- 'eth_signTransaction',
66
- 'eth_sign',
67
- 'personal_sign',
68
- 'eth_sendTransaction',
69
- 'eth_signTypedData_v4',
70
- ],
71
- rpcMap: this.evmNetworkRpcMap(),
72
- },
73
- },
74
- })
75
- .catch((e) => {
76
- logger.error(e);
77
- ee.emit('walletconnect_connection_failed');
78
- });
79
- });
80
- }
81
- createInitProviderPromise() {
82
- return __awaiter(this, void 0, void 0, function* () {
83
- const provider = yield Provider.init({
84
- logger: logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
85
- projectId: this.projectId,
86
- });
87
- WalletConnectV2.provider = provider;
88
- });
89
- }
90
- initProvider() {
91
- return __awaiter(this, void 0, void 0, function* () {
92
- const { provider } = WalletConnectV2;
93
- if (!provider) {
94
- if (this.initializePromise === undefined) {
95
- this.initializePromise = this.createInitProviderPromise();
96
- }
97
- yield this.initializePromise;
98
- }
99
- });
100
- }
101
- refreshSession() {
102
- var _a, _b, _c, _d, _e;
103
- if ((_b = (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) {
104
- if (localStorage.getItem(this.sessionTopicKey) ===
105
- ((_d = (_c = WalletConnectV2.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
106
- this.session = WalletConnectV2.provider.session;
107
- this.activeAccount =
108
- (_e = localStorage.getItem(this.activeAccountKey)) !== null && _e !== void 0 ? _e : undefined;
109
- }
110
- }
111
- }
112
- init() {
113
- return __awaiter(this, void 0, void 0, function* () {
114
- yield this.initProvider();
115
- yield this.initConnection();
116
- this.isInitialized = true;
117
- });
118
- }
119
- get sessionTopicKey() {
120
- return sessionTopicKey(this.key);
121
- }
122
- get activeAccountKey() {
123
- return activeAccountKey(this.key);
124
- }
125
- supportsNetworkSwitching() {
126
- return true;
127
- }
128
- setupEventListeners() {
129
- if (!WalletConnectV2.provider) {
130
- return;
131
- }
132
- WalletConnectV2.provider.client.on('session_event', ({ params }) => {
133
- if (!params || !params.event) {
134
- logger.debug('session_event was called without params or params.event');
135
- return;
136
- }
137
- const { name, data } = params.event;
138
- if (name === 'chainChanged') {
139
- const chainId = parseIntSafe(data);
140
- if (chainId === undefined) {
141
- logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
142
- return;
143
- }
144
- this.emit('chainChange', { chain: String(chainId) });
145
- // When a user switches network from their wallet, we need the provider to change network
146
- // such that any future calls to `getNetwork` will return the correct network
147
- this.switchNetwork({ networkChainId: chainId });
148
- }
149
- else if (name === 'accountsChanged') {
150
- if (!Array.isArray(data)) {
151
- logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
152
- return;
153
- }
154
- // eslint-disable-next-line prefer-destructuring
155
- const account = data[0].split(':')[2];
156
- this.setActiveAccount(account);
157
- this.emit('accountChange', { accounts: [account] });
158
- }
159
- });
160
- WalletConnectV2.provider.client.on('session_delete', () => __awaiter(this, void 0, void 0, function* () {
161
- this.endSession();
162
- this.emit('disconnect');
163
- }));
164
- }
165
- teardownEventListeners() {
166
- if (!WalletConnectV2.provider) {
167
- return;
168
- }
169
- WalletConnectV2.provider.client.removeAllListeners('session_event');
170
- WalletConnectV2.provider.client.removeAllListeners('session_delete');
171
- }
172
- getWeb3Provider() {
173
- if (!WalletConnectV2.provider) {
174
- return;
175
- }
176
- return new ethers.providers.Web3Provider(WalletConnectV2.provider, 'any');
177
- }
178
- fetchPublicAddress(opts) {
179
- var _a, _b;
180
- return __awaiter(this, void 0, void 0, function* () {
181
- if (this.activeAccount) {
182
- return this.activeAccount;
183
- }
184
- if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
185
- logger.debug('No WC2 provider found, re-initializing...');
186
- yield this.endSession();
187
- yield this.init();
188
- // sleep 1 s to wait for connect call to finish
189
- // the connect call isn't await-ed because it only resolves once
190
- // the connection is established, but we need to wait for it to
191
- // finish setting up the connection URI and making it available
192
- // on the provider
193
- yield new Promise((resolve) => setTimeout(resolve, 1000));
194
- if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
195
- logger.debug('No WC2 provider found, escaping and throwing error');
196
- throw new DynamicError('No provider found');
197
- }
198
- }
199
- const metadata = getWalletBookWallet(this.walletBook, this.key);
200
- performPlatformSpecificConnectionMethod(WalletConnectV2.provider.uri, metadata, {
201
- onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
202
- onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
203
- }, this.deepLinkPreference);
204
- return new Promise((resolve, reject) => {
205
- if (!WalletConnectV2.provider) {
206
- reject(new DynamicError('No provider found'));
207
- return;
208
- }
209
- ee.on('walletconnect_connection_failed', () => {
210
- const error = new DynamicError('Connection rejected. Please try again.');
211
- error.code = 'connection_rejected';
212
- if (WalletConnectV2.provider) {
213
- WalletConnectV2.provider.uri = undefined;
214
- }
215
- reject(error);
216
- });
217
- WalletConnectV2.provider.on('connect', ({ session }) => {
218
- if (!session) {
219
- reject(new DynamicError('No session found'));
220
- }
221
- this.setSession(session);
222
- this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
223
- resolve(this.activeAccount);
224
- });
225
- });
226
- });
227
- }
228
- /**
229
- * WalletConnect V2 will fail to send the sign message request if the chainId
230
- * is not the same as the one in the session. This method will wait for the
231
- * chainId to change and then retry the sign message request.
232
- *
233
- * Otherwise it will just return the result of the sign message request.
234
- *
235
- * @param signMessageFn - Function to sign message with provider
236
- * @param messageToSign - Message to sign
237
- * @returns
238
- */
239
- waitForSignMessage(signMessageFn, messageToSign) {
240
- return __awaiter(this, void 0, void 0, function* () {
241
- const raceConditionPromise = new Promise((resolve) => {
242
- // Create listener for chain change event
243
- this.on('chainChange', () => resolve({ success: false }));
244
- signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
245
- });
246
- const signedMessageResult = yield raceConditionPromise;
247
- if (signedMessageResult.success === false) {
248
- return signMessageFn(messageToSign);
249
- }
250
- return signedMessageResult.signedMessage;
251
- });
252
- }
253
- getDeepLink() {
254
- var _a;
255
- if (!this.session) {
256
- return;
257
- }
258
- const metadata = getWalletBookWallet(this.walletBook, this.key);
259
- const deepLink = getDeepLink({
260
- metadata,
261
- mode: 'regular',
262
- preference: this.deepLinkPreference,
263
- uri: (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri,
264
- });
265
- if (!deepLink) {
266
- return;
267
- }
268
- // we need to include the session topic here because it helps the wallet
269
- // auto redirect back to the dapp after signing
270
- return `${deepLink}?sessionTopic=${this.session.topic}`;
271
- }
272
- signMessage(messageToSign) {
273
- return __awaiter(this, void 0, void 0, function* () {
274
- if (!this.session) {
275
- throw new DynamicError('no session');
276
- }
277
- if (!WalletConnectV2.provider) {
278
- throw new DynamicError('No WalletConnect provider found to handle signing');
279
- }
280
- const deepLink = this.getDeepLink();
281
- if (isMobile() && deepLink) {
282
- window.location.href = deepLink;
283
- }
284
- const web3Provider = this.getWeb3Provider();
285
- if (!web3Provider) {
286
- throw new DynamicError('No web3 provider found');
287
- }
288
- const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
289
- return web3Provider.send('personal_sign', [
290
- utf8ToHex(messageToSign, true),
291
- this.activeAccount,
292
- ]);
293
- });
294
- const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
295
- return response;
296
- });
297
- }
298
- clearActiveAccount() {
299
- localStorage.removeItem(this.activeAccountKey);
300
- this.activeAccount = undefined;
301
- }
302
- clearSession() {
303
- localStorage.removeItem(this.sessionTopicKey);
304
- this.session = undefined;
305
- }
306
- setActiveAccount(account) {
307
- localStorage.setItem(this.activeAccountKey, account);
308
- this.activeAccount = account;
309
- }
310
- setSession(session) {
311
- localStorage.setItem(this.sessionTopicKey, session.topic);
312
- this.session = session;
313
- }
314
- endSession() {
315
- var _a;
316
- return __awaiter(this, void 0, void 0, function* () {
317
- this.clearActiveAccount();
318
- this.clearSession();
319
- if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session)) {
320
- return;
321
- }
322
- try {
323
- yield WalletConnectV2.provider.disconnect();
324
- // We must unset provider on logout so that a new session can be established
325
- // If we don't then the provider will still have the old session and will hang
326
- WalletConnectV2.provider = undefined;
327
- this.initializePromise = undefined; // Needed so we can re-initiliza the provider
328
- }
329
- catch (e) {
330
- logger.debug(e);
331
- }
332
- });
333
- }
334
- getNetwork() {
335
- const _super = Object.create(null, {
336
- getNetwork: { get: () => super.getNetwork }
337
- });
338
- return __awaiter(this, void 0, void 0, function* () {
339
- yield this.initProvider();
340
- return _super.getNetwork.call(this);
341
- });
342
- }
343
- providerSwitchNetwork({ network, provider, }) {
344
- const _super = Object.create(null, {
345
- providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
346
- });
347
- return __awaiter(this, void 0, void 0, function* () {
348
- const currentNetworkId = yield this.getNetwork();
349
- if (currentNetworkId && currentNetworkId === network.chainId) {
350
- return;
351
- }
352
- if (this.switchNetworkOnlyFromWallet) {
353
- throw new DynamicError('Network switching is only supported through the wallet');
354
- }
355
- if (!this.supportsNetworkSwitching()) {
356
- throw new DynamicError('Network switching not supported');
357
- }
358
- if (!provider) {
359
- throw new DynamicError('Provider not found');
360
- }
361
- yield _super.providerSwitchNetwork.call(this, { network, provider });
362
- this.emit('chainChange', { chain: String(network.chainId) });
363
- });
364
- }
365
- getConnectedAccounts() {
366
- return __awaiter(this, void 0, void 0, function* () {
367
- yield this.initProvider();
368
- this.refreshSession();
369
- this.isInitialized = true;
370
- if (!this.activeAccount) {
371
- return [];
372
- }
373
- return [this.activeAccount];
374
- });
375
- }
376
- getSupportedNetworks() {
377
- return __awaiter(this, void 0, void 0, function* () {
378
- yield this.initProvider();
379
- this.refreshSession();
380
- if (!this.session) {
381
- return [];
382
- }
383
- const chains = [];
384
- // Some wallet (i.e ZenGo) use namespaces.account to list supported chains
385
- // while others use keys within the namespaces object
386
- Object.keys(this.session.namespaces).forEach((key) => {
387
- if (key.startsWith('eip155:')) {
388
- chains.push(key.split(':')[1]);
389
- }
390
- });
391
- this.session.namespaces.eip155.accounts.forEach((account) => chains.push(account.split(':')[1]));
392
- return chains.length ? chains : undefined;
393
- });
394
- }
11
+ const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
12
+ const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
13
+ const ee = new EventEmitter();
14
+ class WalletConnectV2 extends EthWalletConnector {
15
+ constructor(opts) {
16
+ super(opts);
17
+ this.supportedChains = ['EVM', 'ETH'];
18
+ this.connectedChain = 'EVM';
19
+ this.isInitialized = false;
20
+ this.canConnectViaQrCode = true;
21
+ this.isWalletConnect = true;
22
+ this.preferredChains = [];
23
+ this.name = opts.walletName;
24
+ this.projectId = opts.projectId;
25
+ this.deepLinkPreference = opts.deepLinkPreference || 'native';
26
+ this.preferredChains = opts.walletConnectPreferredChains || [];
27
+ if (!this.preferredChains.includes('eip155:1')) {
28
+ this.preferredChains.push('eip155:1');
29
+ }
30
+ }
31
+ defaultChainId() {
32
+ const preferredNetwork = this.preferredChains.find((chain) => this.supportedChain(chain));
33
+ if (preferredNetwork) {
34
+ return preferredNetwork;
35
+ }
36
+ else if (this.findSupportedChains().length) {
37
+ return this.findSupportedChains()[0];
38
+ }
39
+ else {
40
+ return 'eip155:1';
41
+ }
42
+ }
43
+ findSupportedChains() {
44
+ var _a;
45
+ try {
46
+ const wallet = getWalletBookWallet(this.walletBook, this.key);
47
+ const supportedChains = (_a = this.evmNetworks) === null || _a === void 0 ? void 0 : _a.filter((network) => { var _a; return (_a = wallet === null || wallet === void 0 ? void 0 : wallet.chains) === null || _a === void 0 ? void 0 : _a.includes(`eip155:${network.chainId}`); }).map((network) => `eip155:${network.chainId}`);
48
+ return supportedChains;
49
+ }
50
+ catch (_b) {
51
+ // pass
52
+ }
53
+ return [];
54
+ }
55
+ supportedChain(chainId) {
56
+ var _a;
57
+ return (_a = this.findSupportedChains().filter((chain) => [`eip155:${chainId}`, chainId].includes(chain))) === null || _a === void 0 ? void 0 : _a[0];
58
+ }
59
+ optionalChains() {
60
+ return (this.evmNetworks
61
+ // Filters out mainnet which is required and palm that crashes Trust Wallet
62
+ .filter((network) => network.chainId !== 11297108109 &&
63
+ `eip155:${network.chainId}` !== this.defaultChainId())
64
+ .map((network) => `eip155:${network.chainId}`));
65
+ }
66
+ initConnection() {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const { provider } = WalletConnectV2;
69
+ if (!provider) {
70
+ throw new DynamicError('No provider found (init connection)');
71
+ }
72
+ // this means there is already a connection in progress, so don't call connect again
73
+ if (provider === null || provider === void 0 ? void 0 : provider.uri) {
74
+ return;
75
+ }
76
+ let optionalNamespaces = {};
77
+ if (this.optionalChains().length) {
78
+ optionalNamespaces = {
79
+ eip155: {
80
+ chains: this.optionalChains(),
81
+ events: [],
82
+ methods: [
83
+ 'eth_signTypedData',
84
+ 'eth_signTransaction',
85
+ 'eth_sign',
86
+ 'personal_sign',
87
+ 'eth_sendTransaction',
88
+ 'eth_signTypedData_v4',
89
+ ],
90
+ rpcMap: this.evmNetworkRpcMap(),
91
+ },
92
+ };
93
+ }
94
+ provider
95
+ .connect({
96
+ namespaces: {
97
+ eip155: {
98
+ chains: [this.defaultChainId()],
99
+ events: ['chainChanged', 'accountsChanged'],
100
+ methods: ['personal_sign', 'eth_sendTransaction'],
101
+ rpcMap: this.evmNetworkRpcMap(),
102
+ },
103
+ },
104
+ optionalNamespaces,
105
+ })
106
+ .catch((e) => {
107
+ logger.error(e);
108
+ ee.emit('walletconnect_connection_failed');
109
+ });
110
+ });
111
+ }
112
+ createInitProviderPromise() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ const provider = yield Provider.init({
115
+ logger: logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
116
+ projectId: this.projectId,
117
+ });
118
+ WalletConnectV2.provider = provider;
119
+ });
120
+ }
121
+ initProvider() {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ const { provider } = WalletConnectV2;
124
+ if (!provider) {
125
+ if (this.initializePromise === undefined) {
126
+ this.initializePromise = this.createInitProviderPromise();
127
+ }
128
+ yield this.initializePromise;
129
+ }
130
+ });
131
+ }
132
+ refreshSession() {
133
+ var _a, _b, _c, _d, _e;
134
+ if ((_b = (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) {
135
+ if (localStorage.getItem(this.sessionTopicKey) ===
136
+ ((_d = (_c = WalletConnectV2.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
137
+ this.session = WalletConnectV2.provider.session;
138
+ this.activeAccount = ((_e = localStorage.getItem(this.activeAccountKey)) !== null && _e !== void 0 ? _e : undefined);
139
+ }
140
+ }
141
+ }
142
+ init() {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ yield this.initProvider();
145
+ yield this.initConnection();
146
+ this.isInitialized = true;
147
+ });
148
+ }
149
+ get sessionTopicKey() {
150
+ return sessionTopicKey(this.key);
151
+ }
152
+ get activeAccountKey() {
153
+ return activeAccountKey(this.key);
154
+ }
155
+ supportsNetworkSwitching() {
156
+ return true;
157
+ }
158
+ setupEventListeners() {
159
+ if (!WalletConnectV2.provider) {
160
+ return;
161
+ }
162
+ WalletConnectV2.provider.client.on('session_event', ({ params }) => {
163
+ if (!params || !params.event) {
164
+ logger.debug('session_event was called without params or params.event');
165
+ return;
166
+ }
167
+ const { name, data } = params.event;
168
+ if (name === 'chainChanged') {
169
+ const chainId = parseIntSafe(data);
170
+ if (chainId === undefined) {
171
+ logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
172
+ return;
173
+ }
174
+ this.emit('chainChange', { chain: String(chainId) });
175
+ // When a user switches network from their wallet, we need the provider to change network
176
+ // such that any future calls to `getNetwork` will return the correct network
177
+ this.switchNetwork({ networkChainId: chainId });
178
+ }
179
+ else if (name === 'accountsChanged') {
180
+ if (!Array.isArray(data)) {
181
+ logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
182
+ return;
183
+ }
184
+ // eslint-disable-next-line prefer-destructuring
185
+ const account = data[0].split(':')[2];
186
+ this.setActiveAccount(account);
187
+ this.emit('accountChange', { accounts: [account] });
188
+ }
189
+ });
190
+ WalletConnectV2.provider.client.on('session_delete', () => __awaiter(this, void 0, void 0, function* () {
191
+ this.endSession();
192
+ this.emit('disconnect');
193
+ }));
194
+ }
195
+ teardownEventListeners() {
196
+ if (!WalletConnectV2.provider) {
197
+ return;
198
+ }
199
+ WalletConnectV2.provider.client.removeAllListeners('session_event');
200
+ WalletConnectV2.provider.client.removeAllListeners('session_delete');
201
+ }
202
+ getWalletClient() {
203
+ if (!WalletConnectV2.provider) {
204
+ return;
205
+ }
206
+ return createWalletClient({
207
+ transport: custom(WalletConnectV2.provider),
208
+ });
209
+ }
210
+ fetchPublicAddress(opts) {
211
+ var _a, _b;
212
+ return __awaiter(this, void 0, void 0, function* () {
213
+ if (this.activeAccount) {
214
+ return this.activeAccount;
215
+ }
216
+ if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
217
+ logger.debug('No WC2 provider found, re-initializing...');
218
+ yield this.endSession();
219
+ yield this.init();
220
+ // sleep 1 s to wait for connect call to finish
221
+ // the connect call isn't await-ed because it only resolves once
222
+ // the connection is established, but we need to wait for it to
223
+ // finish setting up the connection URI and making it available
224
+ // on the provider
225
+ yield new Promise((resolve) => setTimeout(resolve, 1000));
226
+ if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
227
+ logger.debug('No WC2 provider found, escaping and throwing error');
228
+ throw new DynamicError('No provider found');
229
+ }
230
+ }
231
+ const metadata = getWalletBookWallet(this.walletBook, this.key);
232
+ performPlatformSpecificConnectionMethod(WalletConnectV2.provider.uri, metadata, {
233
+ onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
234
+ onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
235
+ }, this.deepLinkPreference);
236
+ return new Promise((resolve, reject) => {
237
+ if (!WalletConnectV2.provider) {
238
+ reject(new DynamicError('No provider found'));
239
+ return;
240
+ }
241
+ ee.on('walletconnect_connection_failed', () => {
242
+ const error = new DynamicError('Connection rejected. Please try again.');
243
+ error.code = 'connection_rejected';
244
+ if (WalletConnectV2.provider) {
245
+ WalletConnectV2.provider.uri = undefined;
246
+ }
247
+ reject(error);
248
+ });
249
+ WalletConnectV2.provider.on('connect', ({ session }) => {
250
+ if (!session) {
251
+ reject(new DynamicError('No session found'));
252
+ }
253
+ this.setSession(session);
254
+ this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
255
+ resolve(this.activeAccount);
256
+ });
257
+ });
258
+ });
259
+ }
260
+ /**
261
+ * WalletConnect V2 will fail to send the sign message request if the chainId
262
+ * is not the same as the one in the session. This method will wait for the
263
+ * chainId to change and then retry the sign message request.
264
+ *
265
+ * Otherwise it will just return the result of the sign message request.
266
+ *
267
+ * @param signMessageFn - Function to sign message with provider
268
+ * @param messageToSign - Message to sign
269
+ * @returns
270
+ */
271
+ waitForSignMessage(signMessageFn, messageToSign) {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ const raceConditionPromise = new Promise((resolve) => {
274
+ // Create listener for chain change event
275
+ this.on('chainChange', () => resolve({ success: false }));
276
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
277
+ });
278
+ const signedMessageResult = yield raceConditionPromise;
279
+ if (signedMessageResult.success === false) {
280
+ return signMessageFn(messageToSign);
281
+ }
282
+ return signedMessageResult.signedMessage;
283
+ });
284
+ }
285
+ getDeepLink() {
286
+ var _a;
287
+ if (!this.session) {
288
+ return;
289
+ }
290
+ const metadata = getWalletBookWallet(this.walletBook, this.key);
291
+ const deepLink = getDeepLink({
292
+ metadata,
293
+ mode: 'regular',
294
+ preference: this.deepLinkPreference,
295
+ uri: (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri,
296
+ });
297
+ if (!deepLink) {
298
+ return;
299
+ }
300
+ // we need to include the session topic here because it helps the wallet
301
+ // auto redirect back to the dapp after signing
302
+ return `${deepLink}?sessionTopic=${this.session.topic}`;
303
+ }
304
+ signMessage(messageToSign) {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ if (!this.session) {
307
+ throw new DynamicError('no session');
308
+ }
309
+ const web3Provider = this.getWalletClient();
310
+ if (!web3Provider) {
311
+ throw new DynamicError('No WalletConnect provider found to handle signing');
312
+ }
313
+ const deepLink = this.getDeepLink();
314
+ if (isMobile() && deepLink) {
315
+ window.location.href = deepLink;
316
+ }
317
+ const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
318
+ const { activeAccount } = this;
319
+ if (!activeAccount) {
320
+ return;
321
+ }
322
+ return web3Provider.signMessage({
323
+ account: activeAccount,
324
+ message: messageToSign,
325
+ });
326
+ });
327
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
328
+ return response;
329
+ });
330
+ }
331
+ clearActiveAccount() {
332
+ localStorage.removeItem(this.activeAccountKey);
333
+ this.activeAccount = undefined;
334
+ }
335
+ clearSession() {
336
+ localStorage.removeItem(this.sessionTopicKey);
337
+ this.session = undefined;
338
+ }
339
+ setActiveAccount(account) {
340
+ localStorage.setItem(this.activeAccountKey, account);
341
+ this.activeAccount = account;
342
+ }
343
+ setSession(session) {
344
+ localStorage.setItem(this.sessionTopicKey, session.topic);
345
+ this.session = session;
346
+ }
347
+ endSession() {
348
+ var _a;
349
+ return __awaiter(this, void 0, void 0, function* () {
350
+ this.clearActiveAccount();
351
+ this.clearSession();
352
+ if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session)) {
353
+ return;
354
+ }
355
+ try {
356
+ yield WalletConnectV2.provider.disconnect();
357
+ // We must unset provider on logout so that a new session can be established
358
+ // If we don't then the provider will still have the old session and will hang
359
+ WalletConnectV2.provider = undefined;
360
+ }
361
+ catch (e) {
362
+ logger.debug(e);
363
+ }
364
+ });
365
+ }
366
+ getNetwork() {
367
+ const _super = Object.create(null, {
368
+ getNetwork: { get: () => super.getNetwork }
369
+ });
370
+ return __awaiter(this, void 0, void 0, function* () {
371
+ yield this.initProvider();
372
+ return _super.getNetwork.call(this);
373
+ });
374
+ }
375
+ providerSwitchNetwork({ network, provider, }) {
376
+ const _super = Object.create(null, {
377
+ providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
378
+ });
379
+ return __awaiter(this, void 0, void 0, function* () {
380
+ const currentNetworkId = yield this.getNetwork();
381
+ if (currentNetworkId && currentNetworkId === network.chainId) {
382
+ return;
383
+ }
384
+ if (this.switchNetworkOnlyFromWallet) {
385
+ throw new DynamicError('Network switching is only supported through the wallet');
386
+ }
387
+ if (!this.supportsNetworkSwitching()) {
388
+ throw new DynamicError('Network switching not supported');
389
+ }
390
+ if (!provider) {
391
+ throw new DynamicError('Provider not found');
392
+ }
393
+ yield _super.providerSwitchNetwork.call(this, { network, provider });
394
+ this.emit('chainChange', { chain: String(network.chainId) });
395
+ });
396
+ }
397
+ getConnectedAccounts() {
398
+ return __awaiter(this, void 0, void 0, function* () {
399
+ if (this.isInitialized === false) {
400
+ yield this.initProvider();
401
+ this.refreshSession();
402
+ this.isInitialized = true;
403
+ }
404
+ if (!this.activeAccount) {
405
+ return [];
406
+ }
407
+ return [this.activeAccount];
408
+ });
409
+ }
410
+ getSupportedNetworks() {
411
+ return __awaiter(this, void 0, void 0, function* () {
412
+ yield this.initProvider();
413
+ this.refreshSession();
414
+ if (!this.session) {
415
+ return [];
416
+ }
417
+ const chains = [];
418
+ // Some wallet (i.e ZenGo) use namespaces.account to list supported chains
419
+ // while others use keys within the namespaces object
420
+ Object.keys(this.session.namespaces).forEach((key) => {
421
+ if (key.startsWith('eip155:')) {
422
+ chains.push(key.split(':')[1]);
423
+ }
424
+ });
425
+ this.session.namespaces.eip155.accounts.forEach((account) => chains.push(account.split(':')[1]));
426
+ return chains.length ? chains : undefined;
427
+ });
428
+ }
395
429
  }
396
430
 
397
431
  export { WalletConnectV2 };