@dynamic-labs/solana 4.40.0 → 4.40.2

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 (41) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +12 -12
  5. package/src/CoinbaseSolana/CoinbaseSolana.cjs +4 -0
  6. package/src/CoinbaseSolana/CoinbaseSolana.js +4 -0
  7. package/src/Phantom/Phantom.cjs +4 -0
  8. package/src/Phantom/Phantom.js +4 -0
  9. package/src/SolanaWalletConnectors.cjs +16 -9
  10. package/src/SolanaWalletConnectors.js +16 -9
  11. package/src/Solflare/Solflare.cjs +8 -2
  12. package/src/Solflare/Solflare.d.ts +2 -0
  13. package/src/Solflare/Solflare.js +8 -2
  14. package/src/index.cjs +3 -2
  15. package/src/index.js +3 -2
  16. package/src/injected/BackpackSol/BackpackSol.cjs +8 -2
  17. package/src/injected/BackpackSol/BackpackSol.d.ts +2 -0
  18. package/src/injected/BackpackSol/BackpackSol.js +8 -2
  19. package/src/injected/FallbackSolanaConnector/FallbackSolanaConnector.cjs +4 -0
  20. package/src/injected/FallbackSolanaConnector/FallbackSolanaConnector.js +4 -0
  21. package/src/injected/InjectedWalletBase/InjectedWalletBase.cjs +34 -14
  22. package/src/injected/InjectedWalletBase/InjectedWalletBase.d.ts +8 -0
  23. package/src/injected/InjectedWalletBase/InjectedWalletBase.js +34 -14
  24. package/src/injected/fetchInjectedWalletConnectors.cjs +14 -21
  25. package/src/injected/fetchInjectedWalletConnectors.js +10 -17
  26. package/src/injected/walletStandard/getConnectorConstructorForWalletStandardWallet/getConnectorConstructorForWalletStandardWallet.cjs +7 -2
  27. package/src/injected/walletStandard/getConnectorConstructorForWalletStandardWallet/getConnectorConstructorForWalletStandardWallet.d.ts +1 -1
  28. package/src/injected/walletStandard/getConnectorConstructorForWalletStandardWallet/getConnectorConstructorForWalletStandardWallet.js +7 -2
  29. package/src/utils/getConnectorConstructorInjectedWallet/getConnectorConstructorInjectedWallet.cjs +46 -0
  30. package/src/utils/getConnectorConstructorInjectedWallet/getConnectorConstructorInjectedWallet.d.ts +9 -0
  31. package/src/utils/getConnectorConstructorInjectedWallet/getConnectorConstructorInjectedWallet.js +42 -0
  32. package/src/utils/getConnectorConstructorInjectedWallet/index.d.ts +1 -0
  33. package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.cjs +46 -32
  34. package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.d.ts +4 -3
  35. package/src/walletConnect/SolanaWalletConnectConnector/SolanaWalletConnectConnector.js +47 -33
  36. package/src/walletConnect/utils/addSolanaWalletConnectConnectors/addSolanaWalletConnectConnectors.cjs +64 -0
  37. package/src/walletConnect/utils/addSolanaWalletConnectConnectors/addSolanaWalletConnectConnectors.d.ts +12 -0
  38. package/src/walletConnect/utils/addSolanaWalletConnectConnectors/addSolanaWalletConnectConnectors.js +60 -0
  39. package/src/walletConnect/utils/addSolanaWalletConnectConnectors/index.d.ts +1 -0
  40. package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.cjs +11 -4
  41. package/src/walletConnect/utils/getSolanaWalletConnectConnector/getSolanaWalletConnectConnector.js +11 -4
@@ -1,11 +1,10 @@
1
1
  'use client'
2
- import { findWalletBookWalletByNameAndChain } from '@dynamic-labs/wallet-book';
3
2
  import { getWalletMetadataFromWalletBook } from '@dynamic-labs/wallet-connector-core';
4
3
  import { sanitizeName } from '@dynamic-labs/utils';
5
4
  import { CoinbaseSolana } from '../CoinbaseSolana/CoinbaseSolana.js';
6
5
  import { Solflare } from '../Solflare/Solflare.js';
7
6
  import { logger } from '../utils/logger.js';
8
- import { InjectedWalletBase } from './InjectedWalletBase/InjectedWalletBase.js';
7
+ import { getConnectorConstructorInjectedWallet } from '../utils/getConnectorConstructorInjectedWallet/getConnectorConstructorInjectedWallet.js';
9
8
  import { BackpackSol } from './BackpackSol/BackpackSol.js';
10
9
  import { getConnectorConstructorForWalletStandardWallet } from './walletStandard/getConnectorConstructorForWalletStandardWallet/getConnectorConstructorForWalletStandardWallet.js';
11
10
  import { getWalletStandardWallets } from './walletStandard/getWalletStandardWallets/getWalletStandardWallets.js';
@@ -62,32 +61,26 @@ const fetchInjectedWalletConnectors = ({ walletBook, authMode, }) => {
62
61
  ((_c = (_b = injectedConfig === null || injectedConfig === void 0 ? void 0 : injectedConfig.walletStandard) === null || _b === void 0 ? void 0 : _b.features) === null || _c === void 0 ? void 0 : _c.length);
63
62
  return isSolanaWallet && !shouldBeFiltered;
64
63
  })
65
- .map(([key, wallet]) => {
66
- const { shortName } = wallet;
67
- const name = shortName || wallet.name;
68
- return class extends InjectedWalletBase {
69
- constructor() {
70
- super(...arguments);
71
- this.name = name;
72
- // this is the key from the wallet book entry so that we don't purely rely on the normalized name
73
- this.overrideKey = key;
74
- }
75
- };
76
- });
64
+ .map(([key, wallet]) => getConnectorConstructorInjectedWallet({ key, wallet, walletBook }));
77
65
  const walletStandardWallets = getWalletStandardWallets();
78
66
  const walletStandardConnectors = walletStandardWallets
79
67
  .filter((wallet) => shouldAddWalletStandardConnector(wallet, walletBook, authMode))
80
68
  .map((wallet) => {
81
- const walletBookWallet = findWalletBookWalletByNameAndChain(walletBook, wallet.name, 'sol');
69
+ var _a, _b;
70
+ const [walletBookKey, walletBookWallet] = (_b = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {}).find(([, walletBookEntry]) => {
71
+ var _a, _b;
72
+ return walletBookEntry.name === wallet.name &&
73
+ ((_b = (_a = walletBookEntry.injectedConfig) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.chain) === 'sol';
74
+ })) !== null && _b !== void 0 ? _b : [];
82
75
  // if the wallet book wallet is found, we want to use it to get the metadata
83
76
  // to merge with the wallet standard metadata, specially the supportedHardwareWallets prop
84
77
  const walletBookMetadata = walletBookWallet &&
85
78
  getWalletMetadataFromWalletBook({
86
79
  walletBook,
87
80
  walletBookWallet,
88
- walletKey: `sanitizeName(${wallet.name})sol`,
81
+ walletKey: walletBookKey !== null && walletBookKey !== void 0 ? walletBookKey : `${sanitizeName(wallet.name)}sol`,
89
82
  });
90
- return getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata);
83
+ return getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletBookKey);
91
84
  });
92
85
  logger.logVerboseTroubleshootingMessage('[SOL fetchInjectedWalletConnectors] walletStandardConnectors', walletStandardConnectors.map((w) => w.name));
93
86
  return [...walletBookConnectors, ...walletStandardConnectors];
@@ -7,9 +7,9 @@ var utils = require('@dynamic-labs/utils');
7
7
  var InjectedWalletBase = require('../../InjectedWalletBase/InjectedWalletBase.cjs');
8
8
  var createSolanaSignerFromWalletStandard = require('../createSolanaSignerFromWalletStandard/createSolanaSignerFromWalletStandard.cjs');
9
9
 
10
- const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetadata = {}) => {
10
+ const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetadata = {}, walletBookKey = undefined) => {
11
11
  const sanitizedName = utils.sanitizeName(wallet.name);
12
- return class extends InjectedWalletBase.InjectedWalletBase {
12
+ const ConnectorConstructor = class extends InjectedWalletBase.InjectedWalletBase {
13
13
  constructor(props) {
14
14
  super(Object.assign(Object.assign({}, props), { metadata: Object.assign(Object.assign({}, walletBookMetadata), { groupKey: sanitizedName, icon: wallet.icon, id: sanitizedName, name: wallet.name }) }));
15
15
  this.name = wallet.name;
@@ -23,6 +23,11 @@ const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetada
23
23
  return this._provider;
24
24
  }
25
25
  };
26
+ Object.defineProperty(ConnectorConstructor, 'key', {
27
+ value: walletBookKey !== null && walletBookKey !== void 0 ? walletBookKey : sanitizedName,
28
+ writable: false,
29
+ });
30
+ return ConnectorConstructor;
26
31
  };
27
32
 
28
33
  exports.getConnectorConstructorForWalletStandardWallet = getConnectorConstructorForWalletStandardWallet;
@@ -1,3 +1,3 @@
1
1
  import { Wallet } from '@wallet-standard/base';
2
2
  import { WalletConnectorConstructor, WalletMetadata } from '@dynamic-labs/wallet-connector-core';
3
- export declare const getConnectorConstructorForWalletStandardWallet: (wallet: Wallet, walletBookMetadata?: Partial<WalletMetadata>) => WalletConnectorConstructor;
3
+ export declare const getConnectorConstructorForWalletStandardWallet: (wallet: Wallet, walletBookMetadata?: Partial<WalletMetadata>, walletBookKey?: string | undefined) => WalletConnectorConstructor;
@@ -3,9 +3,9 @@ import { sanitizeName } from '@dynamic-labs/utils';
3
3
  import { InjectedWalletBase } from '../../InjectedWalletBase/InjectedWalletBase.js';
4
4
  import { createSolanaSignerFromWalletStandard } from '../createSolanaSignerFromWalletStandard/createSolanaSignerFromWalletStandard.js';
5
5
 
6
- const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetadata = {}) => {
6
+ const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetadata = {}, walletBookKey = undefined) => {
7
7
  const sanitizedName = sanitizeName(wallet.name);
8
- return class extends InjectedWalletBase {
8
+ const ConnectorConstructor = class extends InjectedWalletBase {
9
9
  constructor(props) {
10
10
  super(Object.assign(Object.assign({}, props), { metadata: Object.assign(Object.assign({}, walletBookMetadata), { groupKey: sanitizedName, icon: wallet.icon, id: sanitizedName, name: wallet.name }) }));
11
11
  this.name = wallet.name;
@@ -19,6 +19,11 @@ const getConnectorConstructorForWalletStandardWallet = (wallet, walletBookMetada
19
19
  return this._provider;
20
20
  }
21
21
  };
22
+ Object.defineProperty(ConnectorConstructor, 'key', {
23
+ value: walletBookKey !== null && walletBookKey !== void 0 ? walletBookKey : sanitizedName,
24
+ writable: false,
25
+ });
26
+ return ConnectorConstructor;
22
27
  };
23
28
 
24
29
  export { getConnectorConstructorForWalletStandardWallet };
@@ -0,0 +1,46 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var InjectedWalletBase = require('../../injected/InjectedWalletBase/InjectedWalletBase.cjs');
7
+
8
+ const getConnectorConstructorInjectedWallet = ({ key, wallet, walletBook, }) => {
9
+ const { shortName } = wallet;
10
+ const name = shortName || wallet.name;
11
+ /**
12
+ * For historical reasons, all wallet connect data for wallets reside in the EVM entry for the wallet in wallet book.
13
+ * Therefore, in order to tell whether this Sol wallet supports wallet connect, we will have to find the wallet book
14
+ * entry that has the wallet connect data for it.
15
+ */
16
+ let walletConnectWalletBookEntry = undefined;
17
+ if (wallet.group) {
18
+ walletConnectWalletBookEntry = Object.values(walletBook.wallets).find((entry) => {
19
+ var _a;
20
+ return entry.walletConnect &&
21
+ entry.group === wallet.group &&
22
+ (
23
+ // Disregard if the wallet connect data does not support Solana. WC chains are prefixed with 'solana:'
24
+ // as they follow CAIP-2 format
25
+ (_a = entry.chains) === null || _a === void 0 ? void 0 : _a.some((chain) => chain.includes('solana:')));
26
+ });
27
+ }
28
+ const InjectedWalletConstructor = class extends InjectedWalletBase.InjectedWalletBase {
29
+ constructor() {
30
+ super(...arguments);
31
+ this.walletName = name;
32
+ this.name = name;
33
+ this.walletConnectWalletBookEntry = walletConnectWalletBookEntry;
34
+ // this is the key from the wallet book entry so that we don't purely rely on the normalized name
35
+ this.overrideKey = key;
36
+ }
37
+ };
38
+ // Add this key so we can later tell which wallet each constructor is for
39
+ Object.defineProperty(InjectedWalletConstructor, 'key', {
40
+ value: key,
41
+ writable: false,
42
+ });
43
+ return InjectedWalletConstructor;
44
+ };
45
+
46
+ exports.getConnectorConstructorInjectedWallet = getConnectorConstructorInjectedWallet;
@@ -0,0 +1,9 @@
1
+ import { WalletBookSchema, WalletSchema } from '@dynamic-labs/wallet-book';
2
+ import { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
3
+ type GetConnectorConstructorInjectedWalletProps = {
4
+ key: string;
5
+ wallet: WalletSchema;
6
+ walletBook: WalletBookSchema;
7
+ };
8
+ export declare const getConnectorConstructorInjectedWallet: ({ key, wallet, walletBook, }: GetConnectorConstructorInjectedWalletProps) => WalletConnectorConstructor;
9
+ export {};
@@ -0,0 +1,42 @@
1
+ 'use client'
2
+ import { InjectedWalletBase } from '../../injected/InjectedWalletBase/InjectedWalletBase.js';
3
+
4
+ const getConnectorConstructorInjectedWallet = ({ key, wallet, walletBook, }) => {
5
+ const { shortName } = wallet;
6
+ const name = shortName || wallet.name;
7
+ /**
8
+ * For historical reasons, all wallet connect data for wallets reside in the EVM entry for the wallet in wallet book.
9
+ * Therefore, in order to tell whether this Sol wallet supports wallet connect, we will have to find the wallet book
10
+ * entry that has the wallet connect data for it.
11
+ */
12
+ let walletConnectWalletBookEntry = undefined;
13
+ if (wallet.group) {
14
+ walletConnectWalletBookEntry = Object.values(walletBook.wallets).find((entry) => {
15
+ var _a;
16
+ return entry.walletConnect &&
17
+ entry.group === wallet.group &&
18
+ (
19
+ // Disregard if the wallet connect data does not support Solana. WC chains are prefixed with 'solana:'
20
+ // as they follow CAIP-2 format
21
+ (_a = entry.chains) === null || _a === void 0 ? void 0 : _a.some((chain) => chain.includes('solana:')));
22
+ });
23
+ }
24
+ const InjectedWalletConstructor = class extends InjectedWalletBase {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.walletName = name;
28
+ this.name = name;
29
+ this.walletConnectWalletBookEntry = walletConnectWalletBookEntry;
30
+ // this is the key from the wallet book entry so that we don't purely rely on the normalized name
31
+ this.overrideKey = key;
32
+ }
33
+ };
34
+ // Add this key so we can later tell which wallet each constructor is for
35
+ Object.defineProperty(InjectedWalletConstructor, 'key', {
36
+ value: key,
37
+ writable: false,
38
+ });
39
+ return InjectedWalletConstructor;
40
+ };
41
+
42
+ export { getConnectorConstructorInjectedWallet };
@@ -0,0 +1 @@
1
+ export { getConnectorConstructorInjectedWallet } from './getConnectorConstructorInjectedWallet';
@@ -4,14 +4,14 @@
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var _tslib = require('../../../_virtual/_tslib.cjs');
7
- var bs58 = require('bs58');
8
- var utils$1 = require('@walletconnect/utils');
9
7
  var web3_js = require('@solana/web3.js');
8
+ var utils$1 = require('@walletconnect/utils');
9
+ var bs58 = require('bs58');
10
10
  var EventEmitter = require('eventemitter3');
11
11
  var solanaCore = require('@dynamic-labs/solana-core');
12
12
  var utils = require('@dynamic-labs/utils');
13
- var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
14
13
  var walletConnect = require('@dynamic-labs/wallet-connect');
14
+ var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
15
15
  var logger = require('../../utils/logger.cjs');
16
16
  var createSolanaSignerForWalletConnect = require('./createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.cjs');
17
17
 
@@ -34,6 +34,9 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
34
34
  if (storedChainId) {
35
35
  this.setNetworkId(storedChainId);
36
36
  }
37
+ if (opts.overrideKey) {
38
+ this.overrideKey = opts.overrideKey;
39
+ }
37
40
  if (!opts.projectId) {
38
41
  throw new utils.DynamicError('WalletConnect project ID is required');
39
42
  }
@@ -47,10 +50,10 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
47
50
  * immediately available.
48
51
  */
49
52
  get signClient() {
50
- if (!this.signClientReference) {
53
+ if (!SolanaWalletConnectConnector.signClientReference) {
51
54
  throw new utils.DynamicError('Failed to access sign client for Wallet Connect Solana: Sign client not initialized');
52
55
  }
53
- return this.signClientReference;
56
+ return SolanaWalletConnectConnector.signClientReference;
54
57
  }
55
58
  getSupportedNetworks() {
56
59
  return _tslib.__awaiter(this, void 0, void 0, function* () {
@@ -92,15 +95,21 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
92
95
  if (this.isInitialized) {
93
96
  return;
94
97
  }
98
+ logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
95
99
  this.isInitialized = true;
100
+ if (SolanaWalletConnectConnector.signClientPromise) {
101
+ yield SolanaWalletConnectConnector.signClientPromise;
102
+ this.setupWCEventListeners();
103
+ return;
104
+ }
96
105
  const { appLogoUrl, appName, projectId } = this.constructorProps;
97
- logger.logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
98
- this.signClientPromise = walletConnect.getSignClientSingleton({
106
+ SolanaWalletConnectConnector.signClientPromise = walletConnect.getSignClientSingleton({
99
107
  appIcon: appLogoUrl !== null && appLogoUrl !== void 0 ? appLogoUrl : '',
100
108
  appName: appName !== null && appName !== void 0 ? appName : '',
101
109
  projectId,
102
110
  });
103
- this.signClientReference = yield this.signClientPromise;
111
+ SolanaWalletConnectConnector.signClientReference =
112
+ yield SolanaWalletConnectConnector.signClientPromise;
104
113
  this.setupWCEventListeners();
105
114
  });
106
115
  }
@@ -178,8 +187,11 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
178
187
  }
179
188
  getAddress(opts) {
180
189
  return _tslib.__awaiter(this, void 0, void 0, function* () {
181
- var _a, _b;
190
+ var _a;
182
191
  logger.logger.debug('[SolanaWalletConnect] getAddress', opts);
192
+ if (this.session) {
193
+ return this.getActiveAddress();
194
+ }
183
195
  /**
184
196
  * In mobile/Safari, if the user just navigates back after the deeplink prompt the connection
185
197
  * is not rejected, so the previous connection URI is still valid and we can use it to handle the connection
@@ -189,24 +201,13 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
189
201
  this.displayUri(opts);
190
202
  return;
191
203
  }
192
- /**
193
- * If we are already connected to a session, we need to end it first
194
- */
195
- yield this.endSession();
196
204
  logger.logger.logVerboseTroubleshootingMessage('[WalletConnectConnector] getAddress', {
197
205
  inAppBrowserUrl: (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.inAppBrowserUrl,
198
206
  isMobile: utils.isMobile(),
199
207
  mobileExperience: this.mobileExperience,
200
208
  });
201
- if (utils.isMobile() &&
202
- ((_b = this.metadata) === null || _b === void 0 ? void 0 : _b.inAppBrowserUrl) &&
203
- this.mobileExperience === 'in-app-browser') {
204
- const inAppBrowserCompiledTemplate = utils.template(this.metadata.inAppBrowserUrl);
205
- const { href } = utils.PlatformService.getUrl();
206
- const deepLink = inAppBrowserCompiledTemplate({
207
- encodedDappURI: encodeURIComponent(href),
208
- });
209
- utils.PlatformService.openURL(deepLink);
209
+ const didOpenInAppBrowser = this.openInAppBrowserIfRequired();
210
+ if (didOpenInAppBrowser) {
210
211
  return;
211
212
  }
212
213
  logger.logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect');
@@ -249,16 +250,29 @@ class SolanaWalletConnectConnector extends solanaCore.SolanaWalletConnector {
249
250
  }
250
251
  const chainHash = (_c = (_b = this.getSelectedNetwork()) === null || _b === void 0 ? void 0 : _b.genesisHash) !== null && _c !== void 0 ? _c : this.solNetworks[0].genesisHash;
251
252
  const chainId = `solana:${chainHash}`;
252
- const requestPromise = this.signClient.request({
253
- chainId,
254
- request: {
255
- method,
256
- params,
257
- },
258
- topic: this.session.topic,
259
- });
260
- this.deepLinkIfApplicable({ method });
261
- return requestPromise;
253
+ try {
254
+ const requestPromise = this.signClient.request({
255
+ chainId,
256
+ request: {
257
+ method,
258
+ params,
259
+ },
260
+ topic: this.session.topic,
261
+ });
262
+ this.deepLinkIfApplicable({ method });
263
+ return yield requestPromise;
264
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
+ }
266
+ catch (error) {
267
+ // If they are throwing a generic error, lets end session to ensure the user will be prompted to reconnect
268
+ // on the next attempt. This should fix the issue.
269
+ // Yes their error message has a typo on "occured"
270
+ if (error.message === 'An error has occured. Please, try again.') {
271
+ yield this.endSession();
272
+ throw new utils.DynamicError('Wallet connection lost. Please, try again.');
273
+ }
274
+ throw error;
275
+ }
262
276
  });
263
277
  }
264
278
  deepLinkIfApplicable(params) {
@@ -1,6 +1,6 @@
1
+ import { SendOptions, Transaction, VersionedTransaction } from '@solana/web3.js';
1
2
  import SignClient from '@walletconnect/sign-client';
2
3
  import type { SessionTypes } from '@walletconnect/types';
3
- import { SendOptions, Transaction, VersionedTransaction } from '@solana/web3.js';
4
4
  import { ISolanaSigner, SolanaWalletConnector, SolanaWalletConnectorOpts } from '@dynamic-labs/solana-core';
5
5
  import { DeepLinkVariant, GetAddressOpts, IWalletConnectConnector } from '@dynamic-labs/wallet-connector-core';
6
6
  export type SolanaWalletConnectConnectorOpts = SolanaWalletConnectorOpts & {
@@ -9,11 +9,12 @@ export type SolanaWalletConnectConnectorOpts = SolanaWalletConnectorOpts & {
9
9
  deepLinkPreference?: DeepLinkVariant;
10
10
  appLogoUrl?: string;
11
11
  appName?: string;
12
+ overrideKey?: string;
12
13
  };
13
14
  export declare class SolanaWalletConnectConnector extends SolanaWalletConnector implements IWalletConnectConnector {
14
15
  name: string;
15
- private signClientReference;
16
- private signClientPromise;
16
+ static signClientReference: SignClient | undefined;
17
+ static signClientPromise: Promise<SignClient> | undefined;
17
18
  /**
18
19
  * When a WalletConnect connection is initiated, we store the connection URI
19
20
  * so we can use it to handle the URI for wallet app connection and still have
@@ -1,13 +1,13 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../_virtual/_tslib.js';
3
- import bs58 from 'bs58';
4
- import { SDK_ERRORS } from '@walletconnect/utils';
5
3
  import { PublicKey, VersionedTransaction, Transaction } from '@solana/web3.js';
4
+ import { SDK_ERRORS } from '@walletconnect/utils';
5
+ import bs58 from 'bs58';
6
6
  import EventEmitter from 'eventemitter3';
7
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';
8
+ import { StorageService, DynamicError, filterDuplicates, isMobile, PlatformService, bufferToBase64 } from '@dynamic-labs/utils';
10
9
  import { getSignClientSingleton } from '@dynamic-labs/wallet-connect';
10
+ import { performPlatformSpecificConnectionMethod, getDeepLink, isSameAddress } from '@dynamic-labs/wallet-connector-core';
11
11
  import { logger } from '../../utils/logger.js';
12
12
  import { createSolanaSignerForWalletConnect } from './createSolanaSignerForWalletConnect/createSolanaSignerForWalletConnect.js';
13
13
 
@@ -25,6 +25,9 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
25
25
  if (storedChainId) {
26
26
  this.setNetworkId(storedChainId);
27
27
  }
28
+ if (opts.overrideKey) {
29
+ this.overrideKey = opts.overrideKey;
30
+ }
28
31
  if (!opts.projectId) {
29
32
  throw new DynamicError('WalletConnect project ID is required');
30
33
  }
@@ -38,10 +41,10 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
38
41
  * immediately available.
39
42
  */
40
43
  get signClient() {
41
- if (!this.signClientReference) {
44
+ if (!SolanaWalletConnectConnector.signClientReference) {
42
45
  throw new DynamicError('Failed to access sign client for Wallet Connect Solana: Sign client not initialized');
43
46
  }
44
- return this.signClientReference;
47
+ return SolanaWalletConnectConnector.signClientReference;
45
48
  }
46
49
  getSupportedNetworks() {
47
50
  return __awaiter(this, void 0, void 0, function* () {
@@ -83,15 +86,21 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
83
86
  if (this.isInitialized) {
84
87
  return;
85
88
  }
89
+ logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
86
90
  this.isInitialized = true;
91
+ if (SolanaWalletConnectConnector.signClientPromise) {
92
+ yield SolanaWalletConnectConnector.signClientPromise;
93
+ this.setupWCEventListeners();
94
+ return;
95
+ }
87
96
  const { appLogoUrl, appName, projectId } = this.constructorProps;
88
- logger.logVerboseTroubleshootingMessage('[SolanaWalletConnect] init called');
89
- this.signClientPromise = getSignClientSingleton({
97
+ SolanaWalletConnectConnector.signClientPromise = getSignClientSingleton({
90
98
  appIcon: appLogoUrl !== null && appLogoUrl !== void 0 ? appLogoUrl : '',
91
99
  appName: appName !== null && appName !== void 0 ? appName : '',
92
100
  projectId,
93
101
  });
94
- this.signClientReference = yield this.signClientPromise;
102
+ SolanaWalletConnectConnector.signClientReference =
103
+ yield SolanaWalletConnectConnector.signClientPromise;
95
104
  this.setupWCEventListeners();
96
105
  });
97
106
  }
@@ -169,8 +178,11 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
169
178
  }
170
179
  getAddress(opts) {
171
180
  return __awaiter(this, void 0, void 0, function* () {
172
- var _a, _b;
181
+ var _a;
173
182
  logger.debug('[SolanaWalletConnect] getAddress', opts);
183
+ if (this.session) {
184
+ return this.getActiveAddress();
185
+ }
174
186
  /**
175
187
  * In mobile/Safari, if the user just navigates back after the deeplink prompt the connection
176
188
  * is not rejected, so the previous connection URI is still valid and we can use it to handle the connection
@@ -180,24 +192,13 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
180
192
  this.displayUri(opts);
181
193
  return;
182
194
  }
183
- /**
184
- * If we are already connected to a session, we need to end it first
185
- */
186
- yield this.endSession();
187
195
  logger.logVerboseTroubleshootingMessage('[WalletConnectConnector] getAddress', {
188
196
  inAppBrowserUrl: (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.inAppBrowserUrl,
189
197
  isMobile: isMobile(),
190
198
  mobileExperience: this.mobileExperience,
191
199
  });
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);
200
+ const didOpenInAppBrowser = this.openInAppBrowserIfRequired();
201
+ if (didOpenInAppBrowser) {
201
202
  return;
202
203
  }
203
204
  logger.debug('[SolanaWalletConnect] getAddress - connecting to WalletConnect');
@@ -240,16 +241,29 @@ class SolanaWalletConnectConnector extends SolanaWalletConnector {
240
241
  }
241
242
  const chainHash = (_c = (_b = this.getSelectedNetwork()) === null || _b === void 0 ? void 0 : _b.genesisHash) !== null && _c !== void 0 ? _c : this.solNetworks[0].genesisHash;
242
243
  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;
244
+ try {
245
+ const requestPromise = this.signClient.request({
246
+ chainId,
247
+ request: {
248
+ method,
249
+ params,
250
+ },
251
+ topic: this.session.topic,
252
+ });
253
+ this.deepLinkIfApplicable({ method });
254
+ return yield requestPromise;
255
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
256
+ }
257
+ catch (error) {
258
+ // If they are throwing a generic error, lets end session to ensure the user will be prompted to reconnect
259
+ // on the next attempt. This should fix the issue.
260
+ // Yes their error message has a typo on "occured"
261
+ if (error.message === 'An error has occured. Please, try again.') {
262
+ yield this.endSession();
263
+ throw new DynamicError('Wallet connection lost. Please, try again.');
264
+ }
265
+ throw error;
266
+ }
253
267
  });
254
268
  }
255
269
  deepLinkIfApplicable(params) {
@@ -0,0 +1,64 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
7
+ var SolanaWalletConnectConnector = require('../../SolanaWalletConnectConnector/SolanaWalletConnectConnector.cjs');
8
+
9
+ /**
10
+ * Adds Solana WalletConnect connectors to the list of connectors, avoiding duplicates
11
+ * by checking what connectors are already present
12
+ */
13
+ const addSolanaWalletConnectConnectors = ({ walletBook, connectors: currentConnectors, }) => {
14
+ var _a;
15
+ const walletEntries = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {});
16
+ const allWcConstructors = walletEntries
17
+ .filter(([, wallet]) => {
18
+ var _a;
19
+ return wallet.walletConnect &&
20
+ (
21
+ // Exclude wallets that don't support Solana
22
+ (_a = wallet.chains) === null || _a === void 0 ? void 0 : _a.some((chain) => chain.includes('solana:')));
23
+ })
24
+ .map(([key, wallet]) => {
25
+ const { shortName } = wallet;
26
+ const name = shortName || wallet.name;
27
+ const SolanaWalletConnectConnectorConstructor = class extends SolanaWalletConnectConnector.SolanaWalletConnectConnector {
28
+ constructor(props) {
29
+ super(Object.assign(Object.assign({}, props), { metadata: walletConnectorCore.getWalletMetadataFromWalletBook({
30
+ walletBookWallet: wallet,
31
+ walletKey: key,
32
+ }), overrideKey: key, walletName: name }));
33
+ this.overrideKey = key;
34
+ }
35
+ };
36
+ const entryKeysWithSameGroup = walletEntries
37
+ .filter(([, { group }]) => group && group === wallet.group)
38
+ .map(([key]) => key);
39
+ // We store the key and the keys of all other entries in the same group
40
+ // so that we can filter out from the WC connectors we just built both the ones
41
+ // whose key is already present in the current connectors and the ones whose key is in the same group
42
+ // as one of the current connectors.
43
+ // We need to check the groups as well because the wallet book entry that we use to create the Sol WC
44
+ // connector might be coming from the EVM wallet book entry (due to historical reasons, that's the entry
45
+ // that has the WC data)
46
+ Object.defineProperty(SolanaWalletConnectConnectorConstructor, 'key', {
47
+ value: key,
48
+ writable: false,
49
+ });
50
+ Object.defineProperty(SolanaWalletConnectConnectorConstructor, 'groupedKeys', {
51
+ value: entryKeysWithSameGroup,
52
+ writable: false,
53
+ });
54
+ return SolanaWalletConnectConnectorConstructor;
55
+ });
56
+ const filteredWcConstructors = allWcConstructors.filter((constructor) => currentConnectors.every((existingConnector) =>
57
+ // @ts-expect-error - the key type is not defined for the constructor
58
+ existingConnector['key'] !== constructor['key'] &&
59
+ // @ts-expect-error - the key type is not defined for the constructor
60
+ !constructor['groupedKeys'].includes(existingConnector['key'])));
61
+ return [...currentConnectors, ...filteredWcConstructors];
62
+ };
63
+
64
+ exports.addSolanaWalletConnectConnectors = addSolanaWalletConnectConnectors;
@@ -0,0 +1,12 @@
1
+ import { WalletBookSchema } from '@dynamic-labs/wallet-book';
2
+ import { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
3
+ type FetchSolanaWalletConnectWalletsProps = {
4
+ walletBook: WalletBookSchema;
5
+ connectors: WalletConnectorConstructor[];
6
+ };
7
+ /**
8
+ * Adds Solana WalletConnect connectors to the list of connectors, avoiding duplicates
9
+ * by checking what connectors are already present
10
+ */
11
+ export declare const addSolanaWalletConnectConnectors: ({ walletBook, connectors: currentConnectors, }: FetchSolanaWalletConnectWalletsProps) => Array<WalletConnectorConstructor>;
12
+ export {};