@dynamic-labs/ethereum 4.8.2-preview.0 → 4.8.3
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 +6 -3
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +10 -9
- package/src/EthereumWalletConnectors.cjs +3 -4
- package/src/EthereumWalletConnectors.js +2 -3
- package/src/injected/InjectedWalletBase.cjs +2 -2
- package/src/injected/InjectedWalletBase.js +2 -2
- package/src/walletConnect/{utils/fetchWalletConnectWallets.cjs → fetchWalletConnectWallets.cjs} +8 -2
- package/src/walletConnect/{utils/fetchWalletConnectWallets.d.ts → fetchWalletConnectWallets.d.ts} +1 -0
- package/src/walletConnect/{utils/fetchWalletConnectWallets.js → fetchWalletConnectWallets.js} +8 -3
- package/src/walletConnect/index.d.ts +2 -2
- package/src/walletConnect/walletConnect.cjs +504 -0
- package/src/walletConnect/{WalletConnectConnector/WalletConnectConnector.d.ts → walletConnect.d.ts} +53 -12
- package/src/walletConnect/walletConnect.js +495 -0
- package/src/walletConnect/WalletConnectConnector/WalletConnectConnector.cjs +0 -286
- package/src/walletConnect/WalletConnectConnector/WalletConnectConnector.js +0 -282
- package/src/walletConnect/WalletConnectConnector/index.d.ts +0 -1
- package/src/walletConnect/WalletConnectProvider/WalletConnectProvider.cjs +0 -169
- package/src/walletConnect/WalletConnectProvider/WalletConnectProvider.d.ts +0 -39
- package/src/walletConnect/WalletConnectProvider/WalletConnectProvider.js +0 -161
- package/src/walletConnect/WalletConnectProvider/index.d.ts +0 -1
- package/src/walletConnect/utils/getWalletConnectConnector.cjs +0 -14
- package/src/walletConnect/utils/getWalletConnectConnector.d.ts +0 -2
- package/src/walletConnect/utils/getWalletConnectConnector.js +0 -10
- package/src/walletConnect/utils/index.d.ts +0 -2
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
7
|
+
var EthereumProvider = require('@walletconnect/ethereum-provider');
|
|
8
|
+
var EventEmitter = require('eventemitter3');
|
|
9
|
+
var viem = require('viem');
|
|
10
|
+
var ethereumCore = require('@dynamic-labs/ethereum-core');
|
|
11
|
+
var utils = require('@dynamic-labs/utils');
|
|
12
|
+
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
13
|
+
|
|
14
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
|
+
|
|
16
|
+
var EthereumProvider__default = /*#__PURE__*/_interopDefaultLegacy(EthereumProvider);
|
|
17
|
+
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
18
|
+
|
|
19
|
+
const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
|
|
20
|
+
const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
|
|
21
|
+
const currentChainKey = (walletName) => `dynamic-wc2-current-chain-${walletName}`;
|
|
22
|
+
const ee = new EventEmitter__default["default"]();
|
|
23
|
+
class WalletConnect extends ethereumCore.EthereumWalletConnector {
|
|
24
|
+
supportsNetworkSwitching() {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
constructor(opts) {
|
|
28
|
+
super(opts);
|
|
29
|
+
this.isInitialized = false;
|
|
30
|
+
this.canConnectViaQrCode = true;
|
|
31
|
+
this.isWalletConnect = true;
|
|
32
|
+
this.preferredChains = [];
|
|
33
|
+
this.sessionEventHandler = () => { };
|
|
34
|
+
this.sessionDeleteHandler = () => { };
|
|
35
|
+
this.name = opts.walletName;
|
|
36
|
+
this.projectId = opts.projectId;
|
|
37
|
+
this.deepLinkPreference = opts.deepLinkPreference || 'native';
|
|
38
|
+
this.preferredChains = opts.walletConnectPreferredChains || [];
|
|
39
|
+
const lsCurrentChain = localStorage.getItem(this.currentChainKey);
|
|
40
|
+
this.currentChainId = lsCurrentChain
|
|
41
|
+
? utils.parseIntSafe(lsCurrentChain)
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* This method is used to get the address of the active account.
|
|
46
|
+
* It will re-initialize the provider if the provider is not found.
|
|
47
|
+
* @param opts
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
getAddress(opts) {
|
|
51
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
const activeAccount = this.getActiveAccount();
|
|
54
|
+
if (activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.address) {
|
|
55
|
+
return activeAccount.address;
|
|
56
|
+
}
|
|
57
|
+
if (!WalletConnect.provider || !((_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.signer.uri)) {
|
|
58
|
+
walletConnectorCore.logger.debug('No WC2 provider found, re-initializing...');
|
|
59
|
+
yield this.endSession();
|
|
60
|
+
yield this.init();
|
|
61
|
+
// sleep 1 s to wait for connect call to finish
|
|
62
|
+
// the connect call isn't await-ed because it only resolves once
|
|
63
|
+
// the connection is established, but we need to wait for it to
|
|
64
|
+
// finish setting up the connection URI and making it available
|
|
65
|
+
// on the provider
|
|
66
|
+
yield utils.sleep(1000);
|
|
67
|
+
if (!WalletConnect.provider || !((_b = WalletConnect.provider) === null || _b === void 0 ? void 0 : _b.signer.uri)) {
|
|
68
|
+
walletConnectorCore.logger.debug('No WC2 provider was found after init attempt, aborting');
|
|
69
|
+
throw new utils.DynamicError('No provider found');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
walletConnectorCore.logger.debug('provider was successfully initialized, continuing');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Set Deep links
|
|
76
|
+
walletConnectorCore.performPlatformSpecificConnectionMethod(WalletConnect.provider.signer.uri, this.metadata.deepLinks, {
|
|
77
|
+
onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
|
|
78
|
+
onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
|
|
79
|
+
}, this.deepLinkPreference);
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
if (!WalletConnect.provider) {
|
|
82
|
+
reject(new utils.DynamicError('No provider found'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const onFail = () => {
|
|
86
|
+
walletConnectorCore.logger.debug('onConnection faile re-initializing provider');
|
|
87
|
+
const error = new utils.DynamicError('Connection rejected. Please try again.');
|
|
88
|
+
error.code = 'connection_rejected';
|
|
89
|
+
if (WalletConnect.provider) {
|
|
90
|
+
WalletConnect.provider.signer.uri = undefined;
|
|
91
|
+
// this is needed for mobile to work when using universal links.
|
|
92
|
+
// if the user cancels the connection, we need to re-initialize the provider
|
|
93
|
+
// so that the async work is done ahead of time, before the user tries to connect again,
|
|
94
|
+
// otherwise they will trigger the iOS bug where they are redirected to the app store
|
|
95
|
+
this.init();
|
|
96
|
+
walletConnectorCore.logger.debug('provider was re-initialized in onConnection fail, continuing');
|
|
97
|
+
}
|
|
98
|
+
reject(error);
|
|
99
|
+
// We must clean up the onConnect and onFail listeners
|
|
100
|
+
// whenever the connection attempt either succeeds or fails
|
|
101
|
+
cleanupListeners();
|
|
102
|
+
};
|
|
103
|
+
const onConnect = () => {
|
|
104
|
+
var _a;
|
|
105
|
+
walletConnectorCore.logger.debug('onConnection success, setting session');
|
|
106
|
+
const session = (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.session;
|
|
107
|
+
if (!session) {
|
|
108
|
+
walletConnectorCore.logger.debug('onConnection success, but no session found rejecting');
|
|
109
|
+
reject(new utils.DynamicError('No session found'));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.setSession(session);
|
|
113
|
+
this.setWCActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
|
|
114
|
+
this.getNetwork().then((chainId) => {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
walletConnectorCore.logger.debug('onConnection success, resolving, chainId:', chainId);
|
|
117
|
+
this.currentChainId = chainId;
|
|
118
|
+
walletConnectorCore.logger.debug('onConnection success, resolving, activeAccountAddress:', (_a = this.getActiveAccount()) === null || _a === void 0 ? void 0 : _a.address);
|
|
119
|
+
resolve((_b = this.getActiveAccount()) === null || _b === void 0 ? void 0 : _b.address);
|
|
120
|
+
});
|
|
121
|
+
// We must clean up the onConnect and onFail listeners
|
|
122
|
+
// whenever the connection attempt either succeeds or fails
|
|
123
|
+
cleanupListeners();
|
|
124
|
+
};
|
|
125
|
+
const cleanupListeners = () => {
|
|
126
|
+
var _a;
|
|
127
|
+
ee.off('walletconnect_connection_failed', onFail);
|
|
128
|
+
(_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.off('connect', onConnect);
|
|
129
|
+
};
|
|
130
|
+
ee.on('walletconnect_connection_failed', onFail);
|
|
131
|
+
WalletConnect.provider.on('connect', onConnect);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
init() {
|
|
136
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
walletConnectorCore.logger.debug('init was called', this.name);
|
|
138
|
+
yield this.initProvider();
|
|
139
|
+
yield this.initConnection();
|
|
140
|
+
this.isInitialized = true;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// We need to add a gate to this method since we will be calling it asynchronously
|
|
144
|
+
// from different places (such as setShowAuthFlow), which means there's a chance for
|
|
145
|
+
// a race condition to happen where createInitProviderPromise is called multiple times
|
|
146
|
+
initProvider() {
|
|
147
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
walletConnectorCore.logger.debug('initProvider was called', this.name);
|
|
149
|
+
const { provider } = WalletConnect;
|
|
150
|
+
if (!provider) {
|
|
151
|
+
walletConnectorCore.logger.debug('provider is undefined', this.name);
|
|
152
|
+
if (this.initializePromise === undefined) {
|
|
153
|
+
this.initializePromise = this.createInitProviderPromise();
|
|
154
|
+
}
|
|
155
|
+
yield this.initializePromise;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
createInitProviderPromise() {
|
|
160
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
WalletConnect.provider = yield this.createProvider();
|
|
162
|
+
this.teardownEventListeners();
|
|
163
|
+
this.setupEventListeners();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
initConnection() {
|
|
167
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
walletConnectorCore.logger.debug('initConnection was called', this.name);
|
|
169
|
+
const { provider } = WalletConnect;
|
|
170
|
+
if (!provider) {
|
|
171
|
+
throw new utils.DynamicError('No provider found (init connection)');
|
|
172
|
+
}
|
|
173
|
+
// this means there is already a connection in progress, so don't call connect again
|
|
174
|
+
if (provider === null || provider === void 0 ? void 0 : provider.signer.uri) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
provider.connect().catch((e) => {
|
|
178
|
+
walletConnectorCore.logger.error(e);
|
|
179
|
+
ee.emit('walletconnect_connection_failed', e);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
createProvider() {
|
|
184
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
walletConnectorCore.logger.debug('createProvider was called', this.name);
|
|
186
|
+
return EthereumProvider__default["default"].init({
|
|
187
|
+
events: ['chainChanged', 'accountsChanged'],
|
|
188
|
+
methods: [],
|
|
189
|
+
optionalChains: this.getMappedChainsByPreferredOrder(),
|
|
190
|
+
optionalMethods: [
|
|
191
|
+
'eth_chainId',
|
|
192
|
+
'eth_signTypedData',
|
|
193
|
+
'eth_signTransaction',
|
|
194
|
+
'eth_sign',
|
|
195
|
+
'personal_sign',
|
|
196
|
+
'eth_sendTransaction',
|
|
197
|
+
'eth_signTypedData_v4',
|
|
198
|
+
'wallet_switchEthereumChain',
|
|
199
|
+
'wallet_addEthereumChain',
|
|
200
|
+
],
|
|
201
|
+
projectId: this.projectId,
|
|
202
|
+
rpcMap: this.evmNetworkRpcMap(),
|
|
203
|
+
showQrModal: false,
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
refreshSession() {
|
|
208
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
209
|
+
var _a, _b, _c, _d, _e, _f;
|
|
210
|
+
walletConnectorCore.logger.debug('refreshSession was called', this.name);
|
|
211
|
+
if (!((_b = (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) ||
|
|
212
|
+
localStorage.getItem(this.sessionTopicKey) !==
|
|
213
|
+
((_d = (_c = WalletConnect.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
|
|
214
|
+
const chain = (_e = this.getMappedChainsByPreferredOrder()) === null || _e === void 0 ? void 0 : _e[0];
|
|
215
|
+
walletConnectorCore.logger.debug('provider is not connected, skipping refreshSession, just setting the default chain', chain);
|
|
216
|
+
this.currentChainId = chain;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
this.session = WalletConnect.provider.session;
|
|
220
|
+
this.setActiveAccount(((_f = localStorage.getItem(this.activeAccountKey)) !== null && _f !== void 0 ? _f : undefined));
|
|
221
|
+
const walletClient = this.getWalletClient();
|
|
222
|
+
const walletChainId = yield walletClient.getChainId();
|
|
223
|
+
walletConnectorCore.logger.debug('checking selected chain in refreshSession', this.name, walletChainId, this.currentChainId);
|
|
224
|
+
if (this.currentChainId && this.currentChainId !== walletChainId) {
|
|
225
|
+
walletConnectorCore.logger.debug('switching to selected chain', this.currentChainId);
|
|
226
|
+
yield walletClient.switchChain({ id: this.currentChainId });
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
getMappedChainsByPreferredOrder() {
|
|
231
|
+
const allChains = this.evmNetworks.map((network) => `eip155:${network.chainId}`);
|
|
232
|
+
const reorderedChains = this.preferredChains.filter((chain) => allChains.includes(chain));
|
|
233
|
+
const remainingChains = allChains.filter((chain) => !this.preferredChains.includes(chain));
|
|
234
|
+
return [...reorderedChains, ...remainingChains].map((chain) => Number(chain.split(':')[1]));
|
|
235
|
+
}
|
|
236
|
+
getWalletClient(chainId) {
|
|
237
|
+
walletConnectorCore.logger.debug('getWalletClient was called', this.name);
|
|
238
|
+
const walletConnect = WalletConnect.provider || this.createProvider();
|
|
239
|
+
const walletClient = viem.createWalletClient({
|
|
240
|
+
account: this.getActiveAccount(),
|
|
241
|
+
chain: ethereumCore.chainsMap[chainId !== null && chainId !== void 0 ? chainId : String(this.currentChainId)],
|
|
242
|
+
transport: viem.custom({
|
|
243
|
+
request: (args) => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
244
|
+
const provider = yield walletConnect;
|
|
245
|
+
return provider.request(args);
|
|
246
|
+
}),
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
return walletClient;
|
|
250
|
+
}
|
|
251
|
+
get currentChainId() {
|
|
252
|
+
return this._currentChainId;
|
|
253
|
+
}
|
|
254
|
+
set currentChainId(value) {
|
|
255
|
+
this._currentChainId = value;
|
|
256
|
+
if (value) {
|
|
257
|
+
localStorage.setItem(this.currentChainKey, value.toString());
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
localStorage.removeItem(this.currentChainKey);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
get sessionTopicKey() {
|
|
264
|
+
return sessionTopicKey(this.key);
|
|
265
|
+
}
|
|
266
|
+
get activeAccountKey() {
|
|
267
|
+
return activeAccountKey(this.key);
|
|
268
|
+
}
|
|
269
|
+
get currentChainKey() {
|
|
270
|
+
return currentChainKey(this.key);
|
|
271
|
+
}
|
|
272
|
+
setupEventListeners() {
|
|
273
|
+
if (!WalletConnect.provider) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
this.sessionEventHandler = ({ params, }) => {
|
|
277
|
+
walletConnectorCore.logger.debug('session_event was called', { params });
|
|
278
|
+
if (!params || !params.event) {
|
|
279
|
+
walletConnectorCore.logger.debug('session_event was called without params or params.event');
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const { name, data } = params.event;
|
|
283
|
+
if (name === 'chainChanged') {
|
|
284
|
+
const chainId = utils.parseIntSafe(data);
|
|
285
|
+
if (chainId === this.currentChainId) {
|
|
286
|
+
walletConnectorCore.logger.debug(`ignoring chainChanged event with same chain id as current chain id: ${chainId}`);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (chainId === undefined) {
|
|
290
|
+
walletConnectorCore.logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
this.currentChainId = chainId;
|
|
294
|
+
this.emit('chainChange', { chain: String(chainId) });
|
|
295
|
+
// When a user switches network from their wallet, we need the provider to change network
|
|
296
|
+
// such that any future calls to `getNetwork` will return the correct network
|
|
297
|
+
this.switchNetwork({ networkChainId: chainId });
|
|
298
|
+
}
|
|
299
|
+
else if (name === 'accountsChanged') {
|
|
300
|
+
if (!Array.isArray(data)) {
|
|
301
|
+
walletConnectorCore.logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// eslint-disable-next-line prefer-destructuring
|
|
305
|
+
const account = data[0].split(':')[2];
|
|
306
|
+
this.setWCActiveAccount(account);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
WalletConnect.provider.on('session_event', this.sessionEventHandler);
|
|
310
|
+
this.sessionDeleteHandler = () => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
this.endSession();
|
|
312
|
+
this.emit('disconnect');
|
|
313
|
+
});
|
|
314
|
+
WalletConnect.provider.on('session_delete', this.sessionDeleteHandler);
|
|
315
|
+
}
|
|
316
|
+
teardownEventListeners() {
|
|
317
|
+
if (!WalletConnect.provider) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
WalletConnect.provider.off('session_event', this.sessionEventHandler);
|
|
321
|
+
WalletConnect.provider.off('session_delete', this.sessionDeleteHandler);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* WalletConnect V2 will fail to send the sign message request if the chainId
|
|
325
|
+
* is not the same as the one in the session. This method will wait for the
|
|
326
|
+
* chainId to change and then retry the sign message request.
|
|
327
|
+
*
|
|
328
|
+
* Otherwise it will just return the result of the sign message request.
|
|
329
|
+
*
|
|
330
|
+
* @param signMessageFn - Function to sign message with provider
|
|
331
|
+
* @param messageToSign - Message to sign
|
|
332
|
+
* @returns
|
|
333
|
+
*/
|
|
334
|
+
waitForSignMessage(signMessageFn, messageToSign) {
|
|
335
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
const raceConditionPromise = new Promise((resolve, reject) => {
|
|
337
|
+
// Create listener for chain change event
|
|
338
|
+
this.on('chainChange', () => resolve({ success: false }));
|
|
339
|
+
signMessageFn(messageToSign)
|
|
340
|
+
.then((result) => resolve({ signedMessage: result, success: true }))
|
|
341
|
+
.catch(reject);
|
|
342
|
+
});
|
|
343
|
+
const signedMessageResult = yield raceConditionPromise;
|
|
344
|
+
if (signedMessageResult.success === false) {
|
|
345
|
+
return signMessageFn(messageToSign);
|
|
346
|
+
}
|
|
347
|
+
return signedMessageResult.signedMessage;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
getDeepLink() {
|
|
351
|
+
var _a;
|
|
352
|
+
if (!this.session) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const deepLink = walletConnectorCore.getDeepLink({
|
|
356
|
+
deepLinks: this.metadata.deepLinks,
|
|
357
|
+
mode: 'regular',
|
|
358
|
+
preference: this.deepLinkPreference,
|
|
359
|
+
uri: (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.signer.uri,
|
|
360
|
+
});
|
|
361
|
+
if (!deepLink) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
// we need to include the session topic here because it helps the wallet
|
|
365
|
+
// auto redirect back to the dapp after signing
|
|
366
|
+
return `${deepLink}?sessionTopic=${this.session.topic}`;
|
|
367
|
+
}
|
|
368
|
+
signMessage(messageToSign) {
|
|
369
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
370
|
+
if (!this.session) {
|
|
371
|
+
throw new utils.DynamicError('no session');
|
|
372
|
+
}
|
|
373
|
+
const deepLink = this.getDeepLink();
|
|
374
|
+
if (utils.isMobile() && deepLink) {
|
|
375
|
+
utils.PlatformService.openURL(deepLink);
|
|
376
|
+
}
|
|
377
|
+
const signMessageFn = (messageToSign) => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
378
|
+
const activeAccount = this.getActiveAccount();
|
|
379
|
+
if (!activeAccount) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const walletClient = yield this.getWalletClient();
|
|
383
|
+
return walletClient.signMessage({
|
|
384
|
+
account: activeAccount,
|
|
385
|
+
message: messageToSign,
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
|
|
389
|
+
return response;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
clearActiveAccount() {
|
|
393
|
+
localStorage.removeItem(this.activeAccountKey);
|
|
394
|
+
this.setActiveAccount(undefined);
|
|
395
|
+
}
|
|
396
|
+
clearSession() {
|
|
397
|
+
localStorage.removeItem(this.sessionTopicKey);
|
|
398
|
+
this.session = undefined;
|
|
399
|
+
}
|
|
400
|
+
setWCActiveAccount(account) {
|
|
401
|
+
localStorage.setItem(this.activeAccountKey, account);
|
|
402
|
+
this.setActiveAccount(account);
|
|
403
|
+
this.emit('accountChange', { accounts: [account] });
|
|
404
|
+
}
|
|
405
|
+
setSession(session) {
|
|
406
|
+
localStorage.setItem(this.sessionTopicKey, session.topic);
|
|
407
|
+
this.session = session;
|
|
408
|
+
}
|
|
409
|
+
endSession() {
|
|
410
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
411
|
+
var _a;
|
|
412
|
+
this.clearActiveAccount();
|
|
413
|
+
this.clearSession();
|
|
414
|
+
this.currentChainId = undefined;
|
|
415
|
+
if (!((_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.session)) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
try {
|
|
419
|
+
yield WalletConnect.provider.disconnect();
|
|
420
|
+
// We must unset provider on logout so that a new session can be established
|
|
421
|
+
// If we don't then the provider will still have the old session and will hang
|
|
422
|
+
WalletConnect.provider = undefined;
|
|
423
|
+
}
|
|
424
|
+
catch (e) {
|
|
425
|
+
walletConnectorCore.logger.debug(e);
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
getNetwork() {
|
|
430
|
+
const _super = Object.create(null, {
|
|
431
|
+
getNetwork: { get: () => super.getNetwork }
|
|
432
|
+
});
|
|
433
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
434
|
+
if (this.currentChainId) {
|
|
435
|
+
return this.currentChainId;
|
|
436
|
+
}
|
|
437
|
+
yield this.initProvider();
|
|
438
|
+
return _super.getNetwork.call(this);
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
providerSwitchNetwork(_a) {
|
|
442
|
+
const _super = Object.create(null, {
|
|
443
|
+
providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
|
|
444
|
+
});
|
|
445
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ network, }) {
|
|
446
|
+
const supportedNetworks = yield this.getSupportedNetworks();
|
|
447
|
+
if (!(supportedNetworks === null || supportedNetworks === void 0 ? void 0 : supportedNetworks.includes(network.chainId.toString()))) {
|
|
448
|
+
const error = new utils.DynamicError('Network switching is not available at this time. The user should manually switch network in their wallet');
|
|
449
|
+
error.code = 'network_switching_only_available_in_wallet';
|
|
450
|
+
throw error;
|
|
451
|
+
}
|
|
452
|
+
const currentNetworkId = yield this.getNetwork();
|
|
453
|
+
if (currentNetworkId && currentNetworkId === network.chainId) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (this.switchNetworkOnlyFromWallet) {
|
|
457
|
+
throw new utils.DynamicError('Network switching is only supported through the wallet');
|
|
458
|
+
}
|
|
459
|
+
const walletClient = yield this.getWalletClient();
|
|
460
|
+
yield _super.providerSwitchNetwork.call(this, { network, provider: walletClient });
|
|
461
|
+
this.currentChainId = network.chainId;
|
|
462
|
+
this.emit('chainChange', { chain: String(network.chainId) });
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
getConnectedAccounts() {
|
|
466
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
467
|
+
if (this.isInitialized === false) {
|
|
468
|
+
// TODO why not just call init()?
|
|
469
|
+
yield this.initProvider();
|
|
470
|
+
yield this.refreshSession();
|
|
471
|
+
this.isInitialized = true;
|
|
472
|
+
}
|
|
473
|
+
const activeAccount = this.getActiveAccount();
|
|
474
|
+
if (!(activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.address)) {
|
|
475
|
+
return [];
|
|
476
|
+
}
|
|
477
|
+
return [activeAccount.address];
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
getSupportedNetworks() {
|
|
481
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
482
|
+
var _a;
|
|
483
|
+
yield this.initProvider();
|
|
484
|
+
yield this.refreshSession();
|
|
485
|
+
if (!this.session) {
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
const chains = [];
|
|
489
|
+
// Some wallet (i.e ZenGo) use namespaces.account to list supported chains
|
|
490
|
+
// while others use keys within the namespaces object
|
|
491
|
+
Object.keys(this.session.namespaces).forEach((key) => {
|
|
492
|
+
if (key.startsWith('eip155:')) {
|
|
493
|
+
chains.push(key.split(':')[1]);
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
(_a = this.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => chains.push(account.split(':')[1]));
|
|
497
|
+
return chains.length
|
|
498
|
+
? chains
|
|
499
|
+
: this.evmNetworks.map((network) => network.chainId.toString());
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
exports.WalletConnect = WalletConnect;
|
package/src/walletConnect/{WalletConnectConnector/WalletConnectConnector.d.ts → walletConnect.d.ts}
RENAMED
|
@@ -1,23 +1,45 @@
|
|
|
1
|
+
import EthereumProvider from '@walletconnect/ethereum-provider';
|
|
2
|
+
import type { SessionTypes } from '@walletconnect/types';
|
|
1
3
|
import { Account, Transport, Chain as ViemChain } from 'viem';
|
|
2
4
|
import { EthereumWalletConnector, EthereumWalletConnectorOpts } from '@dynamic-labs/ethereum-core';
|
|
3
5
|
import { EvmNetwork } from '@dynamic-labs/types';
|
|
4
6
|
import { DeepLinkVariant, GetAddressOpts, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
|
|
5
|
-
export type
|
|
7
|
+
export type WalletConnectOpts = EthereumWalletConnectorOpts & {
|
|
6
8
|
projectId?: string;
|
|
7
9
|
walletName: string;
|
|
8
10
|
deepLinkPreference?: DeepLinkVariant;
|
|
9
11
|
walletConnectPreferredChains?: `eip155:${number}`[];
|
|
10
12
|
};
|
|
11
|
-
export declare class
|
|
13
|
+
export declare class WalletConnect extends EthereumWalletConnector implements IWalletConnectConnector {
|
|
14
|
+
private static provider;
|
|
12
15
|
name: string;
|
|
16
|
+
session: SessionTypes.Struct | undefined;
|
|
17
|
+
isInitialized: boolean;
|
|
18
|
+
initializePromise: Promise<void> | undefined;
|
|
13
19
|
canConnectViaQrCode: boolean;
|
|
14
20
|
isWalletConnect: boolean;
|
|
21
|
+
private projectId?;
|
|
15
22
|
private deepLinkPreference;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
23
|
+
private preferredChains;
|
|
24
|
+
private sessionEventHandler;
|
|
25
|
+
private sessionDeleteHandler;
|
|
26
|
+
private _currentChainId;
|
|
27
|
+
supportsNetworkSwitching(): boolean;
|
|
28
|
+
constructor(opts: WalletConnectOpts);
|
|
29
|
+
/**
|
|
30
|
+
* This method is used to get the address of the active account.
|
|
31
|
+
* It will re-initialize the provider if the provider is not found.
|
|
32
|
+
* @param opts
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
20
35
|
getAddress(opts?: GetAddressOpts): Promise<string | undefined>;
|
|
36
|
+
init(): Promise<void>;
|
|
37
|
+
private initProvider;
|
|
38
|
+
private createInitProviderPromise;
|
|
39
|
+
private initConnection;
|
|
40
|
+
createProvider(): Promise<EthereumProvider>;
|
|
41
|
+
private refreshSession;
|
|
42
|
+
private getMappedChainsByPreferredOrder;
|
|
21
43
|
getWalletClient(chainId?: string): {
|
|
22
44
|
account: Account;
|
|
23
45
|
batch?: {
|
|
@@ -7675,17 +7697,36 @@ export declare class WalletConnectConnector extends EthereumWalletConnector impl
|
|
|
7675
7697
|
uid?: undefined;
|
|
7676
7698
|
} & import("viem").ExactPartial<Pick<import("viem").PublicActions<Transport, ViemChain, Account>, "getChainId" | "prepareTransactionRequest" | "sendRawTransaction" | "call" | "createContractEventFilter" | "createEventFilter" | "estimateContractGas" | "estimateGas" | "getBlock" | "getBlockNumber" | "getContractEvents" | "getEnsText" | "getFilterChanges" | "getGasPrice" | "getLogs" | "getTransaction" | "getTransactionCount" | "getTransactionReceipt" | "readContract" | "simulateContract" | "uninstallFilter" | "watchBlockNumber" | "watchContractEvent"> & Pick<import("viem").WalletActions<ViemChain, Account>, "sendTransaction" | "writeContract">>>(fn: (client: import("viem").Client<Transport, ViemChain, Account, import("viem").WalletRpcSchema, import("viem").WalletActions<ViemChain, Account>>) => client) => import("viem").Client<Transport, ViemChain, Account, import("viem").WalletRpcSchema, { [K_1 in keyof client]: client[K_1]; } & import("viem").WalletActions<ViemChain, Account>>;
|
|
7677
7699
|
};
|
|
7678
|
-
private deepLinkIfApplicable;
|
|
7679
|
-
signMessage(messageToSign: string): Promise<string | undefined>;
|
|
7680
|
-
getConnectedAccounts(): Promise<string[]>;
|
|
7681
|
-
private setWCActiveAccount;
|
|
7682
7700
|
private get currentChainId();
|
|
7683
7701
|
private set currentChainId(value);
|
|
7702
|
+
get sessionTopicKey(): string;
|
|
7703
|
+
get activeAccountKey(): string;
|
|
7704
|
+
get currentChainKey(): string;
|
|
7705
|
+
setupEventListeners(): void;
|
|
7706
|
+
teardownEventListeners(): void;
|
|
7707
|
+
/**
|
|
7708
|
+
* WalletConnect V2 will fail to send the sign message request if the chainId
|
|
7709
|
+
* is not the same as the one in the session. This method will wait for the
|
|
7710
|
+
* chainId to change and then retry the sign message request.
|
|
7711
|
+
*
|
|
7712
|
+
* Otherwise it will just return the result of the sign message request.
|
|
7713
|
+
*
|
|
7714
|
+
* @param signMessageFn - Function to sign message with provider
|
|
7715
|
+
* @param messageToSign - Message to sign
|
|
7716
|
+
* @returns
|
|
7717
|
+
*/
|
|
7718
|
+
protected waitForSignMessage(signMessageFn: (messageToSign: string) => Promise<string | undefined>, messageToSign: string): Promise<string | undefined>;
|
|
7719
|
+
getDeepLink(): string | undefined;
|
|
7720
|
+
signMessage(messageToSign: string): Promise<string | undefined>;
|
|
7721
|
+
private clearActiveAccount;
|
|
7722
|
+
private clearSession;
|
|
7723
|
+
private setWCActiveAccount;
|
|
7724
|
+
private setSession;
|
|
7725
|
+
endSession(): Promise<void>;
|
|
7684
7726
|
getNetwork(): Promise<number | undefined>;
|
|
7685
7727
|
providerSwitchNetwork({ network, }: {
|
|
7686
7728
|
network: EvmNetwork;
|
|
7687
7729
|
}): Promise<void>;
|
|
7688
|
-
|
|
7730
|
+
getConnectedAccounts(): Promise<string[]>;
|
|
7689
7731
|
getSupportedNetworks(): Promise<string[]>;
|
|
7690
|
-
getDeepLink(): string | undefined;
|
|
7691
7732
|
}
|