@dynamic-labs/solana 4.39.0 → 4.40.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 +13 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +17 -12
- package/src/SolanaWalletConnectors.cjs +2 -0
- package/src/SolanaWalletConnectors.js +2 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.cjs +411 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.d.ts +63 -0
- package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.js +402 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.cjs +126 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.d.ts +7 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.js +122 -0
- package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/index.d.ts +1 -0
- package/src/walletConnect/SolanaWalletConnectConnector/index.d.ts +1 -0
- package/src/walletConnect/SolanaWalletConnectConnector/types.d.ts +40 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.cjs +14 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.d.ts +2 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.js +10 -0
- package/src/walletConnect/utils/getSolanaWalletConnectConnector/index.d.ts +1 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import bs58 from 'bs58';
|
|
4
|
+
import { SDK_ERRORS } from '@walletconnect/utils';
|
|
5
|
+
import { PublicKey, VersionedTransaction, Transaction } from '@solana/web3.js';
|
|
6
|
+
import EventEmitter from 'eventemitter3';
|
|
7
|
+
import { SolanaWalletConnector, isVersionedTransaction } from '@dynamic-labs/solana-core';
|
|
8
|
+
import { StorageService, DynamicError, filterDuplicates, isMobile, template, PlatformService, bufferToBase64 } from '@dynamic-labs/utils';
|
|
9
|
+
import { performPlatformSpecificConnectionMethod, getDeepLink, isSameAddress } from '@dynamic-labs/wallet-connector-core';
|
|
10
|
+
import { getSignClientSingleton } from '@dynamic-labs/wallet-connect';
|
|
11
|
+
import { logger } from '../../utils/logger.js';
|
|
12
|
+
import { createSolanaSignerForWalletConnect } from './createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.js';
|
|
13
|
+
|
|
14
|
+
const WC_SOLANA_CURRENT_CHAIN_KEY = 'dynamic-wc2-solana-current-chain';
|
|
15
|
+
class SolanaWalletConnectConnector extends SolanaWalletConnector {
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
super(opts);
|
|
18
|
+
this.activeAccountEmitter = new EventEmitter();
|
|
19
|
+
this.isInitialized = false;
|
|
20
|
+
this.canConnectViaQrCode = true;
|
|
21
|
+
this.isWalletConnect = true;
|
|
22
|
+
this.canHandleMultipleConnections = false;
|
|
23
|
+
this.name = opts.walletName;
|
|
24
|
+
const storedChainId = StorageService.getItem(WC_SOLANA_CURRENT_CHAIN_KEY);
|
|
25
|
+
if (storedChainId) {
|
|
26
|
+
this.setNetworkId(storedChainId);
|
|
27
|
+
}
|
|
28
|
+
if (!opts.projectId) {
|
|
29
|
+
throw new DynamicError('WalletConnect project ID is required');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
get deepLinkPreference() {
|
|
33
|
+
var _a;
|
|
34
|
+
return (_a = this.constructorProps.deepLinkPreference) !== null && _a !== void 0 ? _a : 'native';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Accesses the sign client singleton instance, and throws if it is not
|
|
38
|
+
* immediately available.
|
|
39
|
+
*/
|
|
40
|
+
get signClient() {
|
|
41
|
+
if (!this.signClientReference) {
|
|
42
|
+
throw new DynamicError('Failed to access sign client for Wallet Connect Solana: Sign client not initialized');
|
|
43
|
+
}
|
|
44
|
+
return this.signClientReference;
|
|
45
|
+
}
|
|
46
|
+
getSupportedNetworks() {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
var _a, _b;
|
|
49
|
+
if (!this.session) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const sessionChains = (_b = (_a = this.session.namespaces.solana) === null || _a === void 0 ? void 0 : _a.chains) !== null && _b !== void 0 ? _b : [];
|
|
53
|
+
return this.solNetworks
|
|
54
|
+
.filter((network) => sessionChains.includes(`solana:${network.genesisHash}`))
|
|
55
|
+
.map((network) => network.chainId.toString());
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
getActiveAddress() {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
if (!this.session) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return (_b = (_a = this.session.namespaces.solana) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b[0].split(':')[2];
|
|
64
|
+
}
|
|
65
|
+
listenToActiveAccountChange(listener) {
|
|
66
|
+
this.activeAccountEmitter.on('activeAccountDidChange', listener);
|
|
67
|
+
return () => {
|
|
68
|
+
this.activeAccountEmitter.off('activeAccountDidChange', listener);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
getSigner() {
|
|
72
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
return createSolanaSignerForWalletConnect({ walletConnector: this });
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
connect() {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
throw new Error('Connect method not implemented.');
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
init() {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
if (this.isInitialized) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.isInitialized = true;
|
|
87
|
+
const { appLogoUrl, appName, projectId } = this.constructorProps;
|
|
88
|
+
logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
|
|
89
|
+
this.signClientPromise = getSignClientSingleton({
|
|
90
|
+
appIcon: appLogoUrl !== null && appLogoUrl !== void 0 ? appLogoUrl : '',
|
|
91
|
+
appName: appName !== null && appName !== void 0 ? appName : '',
|
|
92
|
+
projectId,
|
|
93
|
+
});
|
|
94
|
+
this.signClientReference = yield this.signClientPromise;
|
|
95
|
+
this.setupWCEventListeners();
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
setupWCEventListeners() {
|
|
99
|
+
logger.debug('[SolanaWalletConnect] setupWCEventListeners');
|
|
100
|
+
this.signClient.on('session_event', ({ params: { event }, topic }) => {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
// Ignore events for wallets other than the one we are connected to
|
|
103
|
+
if (!this.session || topic !== this.session.topic) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (event.name === 'chainChanged') {
|
|
107
|
+
const chainParam = event.data;
|
|
108
|
+
let chainId = chainParam;
|
|
109
|
+
// Handle potentially CAIP-2 format
|
|
110
|
+
if (chainParam.startsWith('solana:')) {
|
|
111
|
+
const chainHash = chainParam.split(':')[1];
|
|
112
|
+
chainId =
|
|
113
|
+
(_b = (_a = this.solNetworks
|
|
114
|
+
.find((network) => network.genesisHash === chainHash)) === null || _a === void 0 ? void 0 : _a.networkId.toString()) !== null && _b !== void 0 ? _b : chainParam;
|
|
115
|
+
}
|
|
116
|
+
logger.debug('[SolanaWalletConnect] onChainChange', { chainId });
|
|
117
|
+
if (chainId === this.getNetworkId()) {
|
|
118
|
+
logger.debug(`[SolanaWalletConnect] onChainChange - ignoring chainChanged event with same chain id as current chain id: ${chainId}`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// This will already emit an event so no need to call this.emit('chainChange', { chain: chainId });
|
|
122
|
+
this.switchNetwork({ networkChainId: parseInt(chainId) });
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (event.name === 'accountsChanged') {
|
|
126
|
+
const accountsParam = event.data;
|
|
127
|
+
const accounts = filterDuplicates(accountsParam.map((account) => {
|
|
128
|
+
// Handle potentially CAIP-10 format
|
|
129
|
+
if (account.startsWith('solana:')) {
|
|
130
|
+
return account.split(':')[2];
|
|
131
|
+
}
|
|
132
|
+
return account;
|
|
133
|
+
}));
|
|
134
|
+
logger.debug('[SolanaWalletConnect] onAccountChanged', { accounts });
|
|
135
|
+
this.emit('accountChange', { accounts });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (event.name === 'disconnected') {
|
|
139
|
+
logger.debug('[SolanaWalletConnect] onDisconnect');
|
|
140
|
+
this.emit('disconnect');
|
|
141
|
+
this.endSession();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
endSession() {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
logger.debug('[SolanaWalletConnect] endSession');
|
|
149
|
+
this.connectionUri = undefined;
|
|
150
|
+
if (!this.session) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
yield this.signClient.disconnect({
|
|
154
|
+
reason: SDK_ERRORS.USER_DISCONNECTED,
|
|
155
|
+
topic: this.session.topic,
|
|
156
|
+
});
|
|
157
|
+
this.session = undefined;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
displayUri(connectionOpts) {
|
|
161
|
+
if (!this.connectionUri) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
logger.debug('[SolanaWalletConnect] handleDisplayURI', this.connectionUri);
|
|
165
|
+
performPlatformSpecificConnectionMethod(this.connectionUri, this.metadata.deepLinks, {
|
|
166
|
+
onDesktopUri: connectionOpts === null || connectionOpts === void 0 ? void 0 : connectionOpts.onDesktopUri,
|
|
167
|
+
onDisplayUri: connectionOpts === null || connectionOpts === void 0 ? void 0 : connectionOpts.onDisplayUri,
|
|
168
|
+
}, this.deepLinkPreference);
|
|
169
|
+
}
|
|
170
|
+
getAddress(opts) {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
+
var _a, _b;
|
|
173
|
+
logger.debug('[SolanaWalletConnect] getAddress', opts);
|
|
174
|
+
/**
|
|
175
|
+
* In mobile/Safari, if the user just navigates back after the deeplink prompt the connection
|
|
176
|
+
* is not rejected, so the previous connection URI is still valid and we can use it to handle the connection
|
|
177
|
+
*/
|
|
178
|
+
if (this.connectionUri) {
|
|
179
|
+
logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect with existing connection URI');
|
|
180
|
+
this.displayUri(opts);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* If we are already connected to a session, we need to end it first
|
|
185
|
+
*/
|
|
186
|
+
yield this.endSession();
|
|
187
|
+
logger.logVerboseTroubleshootingMessage('[WalletConnectConnector] getAddress', {
|
|
188
|
+
inAppBrowserUrl: (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.inAppBrowserUrl,
|
|
189
|
+
isMobile: isMobile(),
|
|
190
|
+
mobileExperience: this.mobileExperience,
|
|
191
|
+
});
|
|
192
|
+
if (isMobile() &&
|
|
193
|
+
((_b = this.metadata) === null || _b === void 0 ? void 0 : _b.inAppBrowserUrl) &&
|
|
194
|
+
this.mobileExperience === 'in-app-browser') {
|
|
195
|
+
const inAppBrowserCompiledTemplate = template(this.metadata.inAppBrowserUrl);
|
|
196
|
+
const { href } = PlatformService.getUrl();
|
|
197
|
+
const deepLink = inAppBrowserCompiledTemplate({
|
|
198
|
+
encodedDappURI: encodeURIComponent(href),
|
|
199
|
+
});
|
|
200
|
+
PlatformService.openURL(deepLink);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect');
|
|
204
|
+
const chains = this.solNetworks.map((network) => `solana:${network.genesisHash}`);
|
|
205
|
+
try {
|
|
206
|
+
const { approval, uri } = yield this.signClient.connect({
|
|
207
|
+
optionalNamespaces: {
|
|
208
|
+
solana: {
|
|
209
|
+
chains,
|
|
210
|
+
events: ['chainChanged', 'accountsChanged', 'disconnected'],
|
|
211
|
+
methods: [
|
|
212
|
+
'solana_signMessage',
|
|
213
|
+
'solana_signTransaction',
|
|
214
|
+
'solana_requestAccounts',
|
|
215
|
+
'solana_getAccounts',
|
|
216
|
+
'solana_signAllTransactions',
|
|
217
|
+
'solana_signAndSendTransaction',
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
logger.debug('[SolanaWalletConnect] getAddress - connection URI', uri);
|
|
223
|
+
this.connectionUri = uri;
|
|
224
|
+
this.displayUri(opts);
|
|
225
|
+
this.session = yield approval();
|
|
226
|
+
const activeAddress = this.getActiveAddress();
|
|
227
|
+
this.activeAccountEmitter.emit('activeAccountDidChange', activeAddress);
|
|
228
|
+
return activeAddress;
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
this.connectionUri = undefined;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
signClientRequest(_a) {
|
|
236
|
+
return __awaiter(this, arguments, void 0, function* ({ method, params, }) {
|
|
237
|
+
var _b, _c;
|
|
238
|
+
if (!this.session) {
|
|
239
|
+
throw new DynamicError('Session not initialized. Please connect to a wallet first.');
|
|
240
|
+
}
|
|
241
|
+
const chainHash = (_c = (_b = this.getSelectedNetwork()) === null || _b === void 0 ? void 0 : _b.genesisHash) !== null && _c !== void 0 ? _c : this.solNetworks[0].genesisHash;
|
|
242
|
+
const chainId = `solana:${chainHash}`;
|
|
243
|
+
const requestPromise = this.signClient.request({
|
|
244
|
+
chainId,
|
|
245
|
+
request: {
|
|
246
|
+
method,
|
|
247
|
+
params,
|
|
248
|
+
},
|
|
249
|
+
topic: this.session.topic,
|
|
250
|
+
});
|
|
251
|
+
this.deepLinkIfApplicable({ method });
|
|
252
|
+
return requestPromise;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
deepLinkIfApplicable(params) {
|
|
256
|
+
const methodsThatRequireDeepLink = [
|
|
257
|
+
'solana_signMessage',
|
|
258
|
+
'solana_signTransaction',
|
|
259
|
+
'solana_signAllTransactions',
|
|
260
|
+
'solana_signAndSendTransaction',
|
|
261
|
+
];
|
|
262
|
+
const deepLink = this.getDeepLink();
|
|
263
|
+
if (isMobile() &&
|
|
264
|
+
deepLink &&
|
|
265
|
+
methodsThatRequireDeepLink.includes(params.method)) {
|
|
266
|
+
PlatformService.openURL(deepLink);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
signMessage(messageToSign, options) {
|
|
270
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
+
logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] signMessage', messageToSign, options);
|
|
272
|
+
const encodedMessage = new TextEncoder().encode(messageToSign);
|
|
273
|
+
const decodedSignature = yield this.signEncodedMessage(encodedMessage, options);
|
|
274
|
+
return bufferToBase64(decodedSignature);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
signEncodedMessage(encodedMessage, options) {
|
|
278
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
279
|
+
logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] signEncodedMessage', encodedMessage, options);
|
|
280
|
+
if (options === null || options === void 0 ? void 0 : options.address) {
|
|
281
|
+
yield this.validateActiveWallet(options.address);
|
|
282
|
+
}
|
|
283
|
+
const activeAddress = this.getActiveAddress();
|
|
284
|
+
if (!activeAddress) {
|
|
285
|
+
throw new DynamicError('No active address found');
|
|
286
|
+
}
|
|
287
|
+
const { signature } = yield this.signClientRequest({
|
|
288
|
+
method: 'solana_signMessage',
|
|
289
|
+
params: {
|
|
290
|
+
message: bs58.encode(encodedMessage),
|
|
291
|
+
pubkey: new PublicKey(activeAddress).toBase58(),
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
return bs58.decode(signature);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
serializeTransaction(transaction) {
|
|
298
|
+
const serialized = transaction.serialize({
|
|
299
|
+
requireAllSignatures: false,
|
|
300
|
+
verifySignatures: false,
|
|
301
|
+
});
|
|
302
|
+
return bs58.encode(new Uint8Array(serialized));
|
|
303
|
+
}
|
|
304
|
+
signTransaction(transaction) {
|
|
305
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
const activeAddress = this.getActiveAddress();
|
|
307
|
+
if (!activeAddress) {
|
|
308
|
+
throw new DynamicError('Active account address is required');
|
|
309
|
+
}
|
|
310
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
311
|
+
const { transaction: signedTransaction } = yield this.signClientRequest({
|
|
312
|
+
method: 'solana_signTransaction',
|
|
313
|
+
params: { transaction: serializedTransaction },
|
|
314
|
+
});
|
|
315
|
+
const decodedTransaction = bs58.decode(signedTransaction);
|
|
316
|
+
if (isVersionedTransaction(transaction)) {
|
|
317
|
+
return VersionedTransaction.deserialize(decodedTransaction);
|
|
318
|
+
}
|
|
319
|
+
return Transaction.from(decodedTransaction);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
signAllTransactions(transactions) {
|
|
323
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
324
|
+
const serializedTransactions = transactions.map(this.serializeTransaction);
|
|
325
|
+
const { transactions: signedTransactions } = yield this.signClientRequest({
|
|
326
|
+
method: 'solana_signAllTransactions',
|
|
327
|
+
params: { transactions: serializedTransactions },
|
|
328
|
+
});
|
|
329
|
+
return signedTransactions.map((signedTransaction, index) => {
|
|
330
|
+
const originalTransaction = transactions[index];
|
|
331
|
+
const decodedTransaction = bs58.decode(signedTransaction);
|
|
332
|
+
if (isVersionedTransaction(originalTransaction)) {
|
|
333
|
+
return VersionedTransaction.deserialize(decodedTransaction);
|
|
334
|
+
}
|
|
335
|
+
return Transaction.from(decodedTransaction);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
signAndSendTransaction(transaction, options) {
|
|
340
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
341
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
342
|
+
const { signature } = yield this.signClientRequest({
|
|
343
|
+
method: 'solana_signAndSendTransaction',
|
|
344
|
+
params: { options, transaction: serializedTransaction },
|
|
345
|
+
});
|
|
346
|
+
return signature;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
getDeepLink() {
|
|
350
|
+
const deepLink = getDeepLink({
|
|
351
|
+
deepLinks: this.metadata.deepLinks,
|
|
352
|
+
mode: 'regular',
|
|
353
|
+
preference: this.deepLinkPreference,
|
|
354
|
+
// TODO: verify whether we need the uri
|
|
355
|
+
// uri: provider.signer.uri,
|
|
356
|
+
});
|
|
357
|
+
logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] getDeepLink - deepLink', deepLink);
|
|
358
|
+
if (!deepLink) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (this.session) {
|
|
362
|
+
// we need to include the session topic here because it helps the wallet
|
|
363
|
+
// auto redirect back to the dapp after signing
|
|
364
|
+
return `${deepLink}?sessionTopic=${this.session.topic}`;
|
|
365
|
+
}
|
|
366
|
+
return deepLink;
|
|
367
|
+
}
|
|
368
|
+
getConnectedAccounts() {
|
|
369
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
370
|
+
/**
|
|
371
|
+
* Each session has a single account (it might be on multiple chains hence the array),
|
|
372
|
+
* but that account is stored as a CAIP-10 string, so we need to parse it to get the address
|
|
373
|
+
*/
|
|
374
|
+
const account = this.getActiveAddress();
|
|
375
|
+
if (!account) {
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] getConnectedAccounts - activeAccounts', [account]);
|
|
379
|
+
return [account];
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
getConnectionUri() {
|
|
383
|
+
return this.connectionUri;
|
|
384
|
+
}
|
|
385
|
+
validateActiveWallet(expectedAddress) {
|
|
386
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
387
|
+
logger.debug('[SolanaWalletConnect] validateActiveWallet - validating wallet', expectedAddress);
|
|
388
|
+
const [activeAddress] = yield this.getConnectedAccounts();
|
|
389
|
+
const isWalletActive = isSameAddress(activeAddress, expectedAddress, this.connectedChain);
|
|
390
|
+
if (isWalletActive) {
|
|
391
|
+
logger.debug('[SolanaWalletConnect] validateActiveWallet - wallet is active');
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
return this.handleWalletNotActive({
|
|
395
|
+
activeAddress,
|
|
396
|
+
expectedAddress,
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export { SolanaWalletConnectConnector };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var _tslib = require('../../../../_virtual/_tslib.cjs');
|
|
7
|
+
var web3_js = require('@solana/web3.js');
|
|
8
|
+
var utils = require('@dynamic-labs/utils');
|
|
9
|
+
var logger = require('../../../utils/logger.cjs');
|
|
10
|
+
|
|
11
|
+
const createSolanaSignerForWalletConnect = ({ walletConnector, }) => {
|
|
12
|
+
const connect = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const address = walletConnector.getActiveAddress();
|
|
14
|
+
if (!address) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return { address, publicKey: new web3_js.PublicKey(address) };
|
|
18
|
+
});
|
|
19
|
+
// eslint-disable-next-line arrow-body-style
|
|
20
|
+
const disconnect = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
yield walletConnector.endSession();
|
|
22
|
+
});
|
|
23
|
+
const on = (event, listener) => {
|
|
24
|
+
if (event === 'connect') {
|
|
25
|
+
logger.logger.debug('on - Not implemented for event: connect');
|
|
26
|
+
return signer;
|
|
27
|
+
}
|
|
28
|
+
if (event === 'activeWalletDidChange') {
|
|
29
|
+
walletConnector.listenToActiveAccountChange(listener);
|
|
30
|
+
return signer;
|
|
31
|
+
}
|
|
32
|
+
walletConnector.signClient.on('session_event', (sessionEvent) => {
|
|
33
|
+
// Skip events from other sessions
|
|
34
|
+
if (!walletConnector.session ||
|
|
35
|
+
sessionEvent.topic !== walletConnector.session.topic) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (sessionEvent.params.event.name === 'accountsChanged' &&
|
|
39
|
+
event === 'accountChanged') {
|
|
40
|
+
const accountsParam = sessionEvent.params.event.data;
|
|
41
|
+
const accounts = utils.filterDuplicates(accountsParam.map((account) => {
|
|
42
|
+
// Handle potentially CAIP-10 format
|
|
43
|
+
if (account.startsWith('solana:')) {
|
|
44
|
+
return account.split(':')[2];
|
|
45
|
+
}
|
|
46
|
+
return account;
|
|
47
|
+
}));
|
|
48
|
+
listener(accounts[0]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (sessionEvent.params.event.name === 'disconnected' &&
|
|
52
|
+
event === 'disconnect') {
|
|
53
|
+
listener('');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return signer;
|
|
58
|
+
};
|
|
59
|
+
const signMessage = (messageArrayBuffer) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
const signature = yield walletConnector.signEncodedMessage(messageArrayBuffer);
|
|
61
|
+
return { signature };
|
|
62
|
+
});
|
|
63
|
+
const signAllTransactions = (transactions) => _tslib.__awaiter(void 0, void 0, void 0, function* () { return walletConnector.signAllTransactions(transactions); });
|
|
64
|
+
const signAndSendTransaction = (transaction, options) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const signature = yield walletConnector.signAndSendTransaction(transaction, options);
|
|
66
|
+
return { signature };
|
|
67
|
+
});
|
|
68
|
+
const signTransaction = (transaction) => _tslib.__awaiter(void 0, void 0, void 0, function* () { return walletConnector.signTransaction(transaction); });
|
|
69
|
+
const signer = {
|
|
70
|
+
addListener: () => {
|
|
71
|
+
throw new Error('addListener - Not implemented');
|
|
72
|
+
},
|
|
73
|
+
connect,
|
|
74
|
+
disconnect,
|
|
75
|
+
emit: () => {
|
|
76
|
+
throw new Error('emit - Not implemented');
|
|
77
|
+
},
|
|
78
|
+
eventNames: () => {
|
|
79
|
+
logger.logger.error('eventNames - Not implemented');
|
|
80
|
+
return [];
|
|
81
|
+
},
|
|
82
|
+
isBackpack: false,
|
|
83
|
+
isBraveWallet: false,
|
|
84
|
+
get isConnected() {
|
|
85
|
+
return Boolean(walletConnector.getActiveAddress());
|
|
86
|
+
},
|
|
87
|
+
isExodus: false,
|
|
88
|
+
isGlow: false,
|
|
89
|
+
isMagicEden: false,
|
|
90
|
+
isPhantom: false,
|
|
91
|
+
isSolflare: false,
|
|
92
|
+
listenerCount: () => {
|
|
93
|
+
logger.logger.error('listenerCount - Not implemented');
|
|
94
|
+
return 0;
|
|
95
|
+
},
|
|
96
|
+
listeners: () => {
|
|
97
|
+
logger.logger.error('listeners - Not implemented');
|
|
98
|
+
return [];
|
|
99
|
+
},
|
|
100
|
+
off: () => {
|
|
101
|
+
throw new Error('off - Not implemented');
|
|
102
|
+
},
|
|
103
|
+
on,
|
|
104
|
+
once: () => {
|
|
105
|
+
throw new Error('once - Not implemented');
|
|
106
|
+
},
|
|
107
|
+
providers: [],
|
|
108
|
+
get publicKey() {
|
|
109
|
+
const address = walletConnector.getActiveAddress();
|
|
110
|
+
return address ? new web3_js.PublicKey(address) : undefined;
|
|
111
|
+
},
|
|
112
|
+
removeAllListeners: () => {
|
|
113
|
+
throw new Error('removeAllListeners - Not implemented');
|
|
114
|
+
},
|
|
115
|
+
removeListener: () => {
|
|
116
|
+
throw new Error('removeListener - Not implemented');
|
|
117
|
+
},
|
|
118
|
+
signAllTransactions,
|
|
119
|
+
signAndSendTransaction,
|
|
120
|
+
signMessage,
|
|
121
|
+
signTransaction,
|
|
122
|
+
};
|
|
123
|
+
return signer;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
exports.createSolanaSignerForWalletConnect = createSolanaSignerForWalletConnect;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ISolanaSigner } from '@dynamic-labs/solana-core';
|
|
2
|
+
import { SolanaWalletConnectConnector } from '../SolanaWalletConnectConnector';
|
|
3
|
+
type CreateSolanaSignerForWalletConnectProps = {
|
|
4
|
+
walletConnector: SolanaWalletConnectConnector;
|
|
5
|
+
};
|
|
6
|
+
export declare const createSolanaSignerForWalletConnect: ({ walletConnector, }: CreateSolanaSignerForWalletConnectProps) => ISolanaSigner;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../../_virtual/_tslib.js';
|
|
3
|
+
import { PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { filterDuplicates } from '@dynamic-labs/utils';
|
|
5
|
+
import { logger } from '../../../utils/logger.js';
|
|
6
|
+
|
|
7
|
+
const createSolanaSignerForWalletConnect = ({ walletConnector, }) => {
|
|
8
|
+
const connect = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
9
|
+
const address = walletConnector.getActiveAddress();
|
|
10
|
+
if (!address) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
return { address, publicKey: new PublicKey(address) };
|
|
14
|
+
});
|
|
15
|
+
// eslint-disable-next-line arrow-body-style
|
|
16
|
+
const disconnect = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
yield walletConnector.endSession();
|
|
18
|
+
});
|
|
19
|
+
const on = (event, listener) => {
|
|
20
|
+
if (event === 'connect') {
|
|
21
|
+
logger.debug('on - Not implemented for event: connect');
|
|
22
|
+
return signer;
|
|
23
|
+
}
|
|
24
|
+
if (event === 'activeWalletDidChange') {
|
|
25
|
+
walletConnector.listenToActiveAccountChange(listener);
|
|
26
|
+
return signer;
|
|
27
|
+
}
|
|
28
|
+
walletConnector.signClient.on('session_event', (sessionEvent) => {
|
|
29
|
+
// Skip events from other sessions
|
|
30
|
+
if (!walletConnector.session ||
|
|
31
|
+
sessionEvent.topic !== walletConnector.session.topic) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (sessionEvent.params.event.name === 'accountsChanged' &&
|
|
35
|
+
event === 'accountChanged') {
|
|
36
|
+
const accountsParam = sessionEvent.params.event.data;
|
|
37
|
+
const accounts = filterDuplicates(accountsParam.map((account) => {
|
|
38
|
+
// Handle potentially CAIP-10 format
|
|
39
|
+
if (account.startsWith('solana:')) {
|
|
40
|
+
return account.split(':')[2];
|
|
41
|
+
}
|
|
42
|
+
return account;
|
|
43
|
+
}));
|
|
44
|
+
listener(accounts[0]);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (sessionEvent.params.event.name === 'disconnected' &&
|
|
48
|
+
event === 'disconnect') {
|
|
49
|
+
listener('');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return signer;
|
|
54
|
+
};
|
|
55
|
+
const signMessage = (messageArrayBuffer) => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
const signature = yield walletConnector.signEncodedMessage(messageArrayBuffer);
|
|
57
|
+
return { signature };
|
|
58
|
+
});
|
|
59
|
+
const signAllTransactions = (transactions) => __awaiter(void 0, void 0, void 0, function* () { return walletConnector.signAllTransactions(transactions); });
|
|
60
|
+
const signAndSendTransaction = (transaction, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
const signature = yield walletConnector.signAndSendTransaction(transaction, options);
|
|
62
|
+
return { signature };
|
|
63
|
+
});
|
|
64
|
+
const signTransaction = (transaction) => __awaiter(void 0, void 0, void 0, function* () { return walletConnector.signTransaction(transaction); });
|
|
65
|
+
const signer = {
|
|
66
|
+
addListener: () => {
|
|
67
|
+
throw new Error('addListener - Not implemented');
|
|
68
|
+
},
|
|
69
|
+
connect,
|
|
70
|
+
disconnect,
|
|
71
|
+
emit: () => {
|
|
72
|
+
throw new Error('emit - Not implemented');
|
|
73
|
+
},
|
|
74
|
+
eventNames: () => {
|
|
75
|
+
logger.error('eventNames - Not implemented');
|
|
76
|
+
return [];
|
|
77
|
+
},
|
|
78
|
+
isBackpack: false,
|
|
79
|
+
isBraveWallet: false,
|
|
80
|
+
get isConnected() {
|
|
81
|
+
return Boolean(walletConnector.getActiveAddress());
|
|
82
|
+
},
|
|
83
|
+
isExodus: false,
|
|
84
|
+
isGlow: false,
|
|
85
|
+
isMagicEden: false,
|
|
86
|
+
isPhantom: false,
|
|
87
|
+
isSolflare: false,
|
|
88
|
+
listenerCount: () => {
|
|
89
|
+
logger.error('listenerCount - Not implemented');
|
|
90
|
+
return 0;
|
|
91
|
+
},
|
|
92
|
+
listeners: () => {
|
|
93
|
+
logger.error('listeners - Not implemented');
|
|
94
|
+
return [];
|
|
95
|
+
},
|
|
96
|
+
off: () => {
|
|
97
|
+
throw new Error('off - Not implemented');
|
|
98
|
+
},
|
|
99
|
+
on,
|
|
100
|
+
once: () => {
|
|
101
|
+
throw new Error('once - Not implemented');
|
|
102
|
+
},
|
|
103
|
+
providers: [],
|
|
104
|
+
get publicKey() {
|
|
105
|
+
const address = walletConnector.getActiveAddress();
|
|
106
|
+
return address ? new PublicKey(address) : undefined;
|
|
107
|
+
},
|
|
108
|
+
removeAllListeners: () => {
|
|
109
|
+
throw new Error('removeAllListeners - Not implemented');
|
|
110
|
+
},
|
|
111
|
+
removeListener: () => {
|
|
112
|
+
throw new Error('removeListener - Not implemented');
|
|
113
|
+
},
|
|
114
|
+
signAllTransactions,
|
|
115
|
+
signAndSendTransaction,
|
|
116
|
+
signMessage,
|
|
117
|
+
signTransaction,
|
|
118
|
+
};
|
|
119
|
+
return signer;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export { createSolanaSignerForWalletConnect };
|
package/src/walletConnect/SolanaWalletConnectConnector/createSolanaSignerForWalletConnect/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSolanaSignerForWalletConnect } from './createSolanaSignerForWalletConnect';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SolanaWalletConnectConnector } from './SolanaWalletConnectConnector';
|