@dynamic-labs/solana 4.87.2 → 4.88.1

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 CHANGED
@@ -1,4 +1,23 @@
1
1
 
2
+ ### [4.88.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.88.0...v4.88.1) (2026-06-04)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * **solana:** poll wallet-standard registry to catch late-injecting wallets ([#11464](https://github.com/dynamic-labs/dynamic-auth/issues/11464)) ([afa8ae7](https://github.com/dynamic-labs/dynamic-auth/commit/afa8ae785d7be58775addc4bb2db3dc1b5500f87))
8
+
9
+ ## [4.88.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.87.2...v4.88.0) (2026-06-04)
10
+
11
+
12
+ ### Features
13
+
14
+ * **waas:** log out on iframe 401 ([#11456](https://github.com/dynamic-labs/dynamic-auth/issues/11456)) ([81b0161](https://github.com/dynamic-labs/dynamic-auth/commit/81b01617810af8f7f996fdbf406e020b9f98272b))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **starknet:** zero-pad addresses returned by wallet connectors ([#11303](https://github.com/dynamic-labs/dynamic-auth/issues/11303)) ([ef5cda5](https://github.com/dynamic-labs/dynamic-auth/commit/ef5cda5a9933443195b3bd336db8947c2ec050b7))
20
+
2
21
  ### [4.87.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.87.1...v4.87.2) (2026-06-03)
3
22
 
4
23
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.87.2";
6
+ var version = "4.88.1";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.87.2";
2
+ var version = "4.88.1";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/solana",
3
- "version": "4.87.2",
3
+ "version": "4.88.1",
4
4
  "description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "homepage": "https://www.dynamic.xyz/",
20
20
  "dependencies": {
21
- "@dynamic-labs/wallet-connect": "4.87.2",
21
+ "@dynamic-labs/wallet-connect": "4.88.1",
22
22
  "@dynamic-labs-connectors/metamask-solana": "4.6.7",
23
23
  "@solana/web3.js": "1.98.1",
24
24
  "@wallet-standard/app": "1.0.1",
@@ -30,17 +30,17 @@
30
30
  "@walletconnect/sign-client": "2.21.5",
31
31
  "@walletconnect/utils": "2.21.5",
32
32
  "@walletconnect/types": "2.21.5",
33
- "@dynamic-labs/assert-package-version": "4.87.2",
34
- "@dynamic-labs/embedded-wallet-solana": "4.87.2",
35
- "@dynamic-labs/logger": "4.87.2",
36
- "@dynamic-labs/rpc-providers": "4.87.2",
33
+ "@dynamic-labs/assert-package-version": "4.88.1",
34
+ "@dynamic-labs/embedded-wallet-solana": "4.88.1",
35
+ "@dynamic-labs/logger": "4.88.1",
36
+ "@dynamic-labs/rpc-providers": "4.88.1",
37
37
  "@dynamic-labs/sdk-api-core": "0.0.1015",
38
- "@dynamic-labs/solana-core": "4.87.2",
39
- "@dynamic-labs/types": "4.87.2",
40
- "@dynamic-labs/utils": "4.87.2",
41
- "@dynamic-labs/waas-svm": "4.87.2",
42
- "@dynamic-labs/wallet-book": "4.87.2",
43
- "@dynamic-labs/wallet-connector-core": "4.87.2",
38
+ "@dynamic-labs/solana-core": "4.88.1",
39
+ "@dynamic-labs/types": "4.88.1",
40
+ "@dynamic-labs/utils": "4.88.1",
41
+ "@dynamic-labs/waas-svm": "4.88.1",
42
+ "@dynamic-labs/wallet-book": "4.88.1",
43
+ "@dynamic-labs/wallet-connector-core": "4.88.1",
44
44
  "eventemitter3": "5.0.1"
45
45
  },
46
46
  "peerDependencies": {}
@@ -15,7 +15,17 @@ var getConnectorConstructorForWalletStandardWallet = require('./walletStandard/g
15
15
  var getWalletStandardWallets = require('./walletStandard/getWalletStandardWallets/getWalletStandardWallets.cjs');
16
16
  var hasAllWalletStandardRequiredFeatures = require('./walletStandard/hasAllWalletStandardRequiredFeatures/hasAllWalletStandardRequiredFeatures.cjs');
17
17
 
18
- let removeSolanaWalletStandardListener = null;
18
+ /**
19
+ * Teardown for the active wallet-standard discovery (register listener + poll).
20
+ * Recreated on each fetchInjectedWalletConnectors call.
21
+ */
22
+ let teardownSolanaWalletStandardDiscovery = null;
23
+ // Some extensions (e.g. Backpack/Eden/Solflare racing over the page) inject
24
+ // after the initial snapshot, and a one-shot register listener can miss an
25
+ // announcement that fires before we subscribe. Polling the wallet-standard
26
+ // registry for a short window catches those late arrivals without a refresh.
27
+ const SOLANA_WALLET_STANDARD_POLL_INTERVAL_MS = 300;
28
+ const SOLANA_WALLET_STANDARD_POLL_DURATION_MS = 5000;
19
29
  const injectedWalletOverrides = [
20
30
  CoinbaseSolana.CoinbaseSolana,
21
31
  BackpackSol.BackpackSol,
@@ -55,38 +65,69 @@ const shouldAddWalletStandardConnector = (wallet, walletBook, authMode) => {
55
65
  });
56
66
  return !shouldHandleFromWalletBook && hasAllFeatures;
57
67
  };
58
- const addSolanaWalletStandardListener = (walletBook$1, authMode) => {
68
+ const emitWalletStandardConnector = (wallet, walletBook$1) => {
69
+ var _a, _b;
70
+ logger.logger.logVerboseTroubleshootingMessage('[SOL fetchInjectedWalletConnectors] Emitting providerInjected for wallet-standard wallet', wallet.name);
71
+ const walletBookWallet = walletBook.findWalletBookWalletByNameAndChain(walletBook$1, wallet.name, 'sol');
72
+ const walletKey = walletBookWallet
73
+ ? (_b = Object.entries((_a = walletBook$1 === null || walletBook$1 === void 0 ? void 0 : walletBook$1.wallets) !== null && _a !== void 0 ? _a : {}).find(([, entry]) => entry === walletBookWallet)) === null || _b === void 0 ? void 0 : _b[0]
74
+ : undefined;
75
+ const walletBookMetadata = walletBookWallet &&
76
+ walletConnectorCore.getWalletMetadataFromWalletBook({
77
+ walletBook: walletBook$1,
78
+ walletBookWallet,
79
+ walletKey: walletKey !== null && walletKey !== void 0 ? walletKey : `${utils.sanitizeName(wallet.name)}sol`,
80
+ });
81
+ const injectedConnectorConstructor = getConnectorConstructorForWalletStandardWallet.getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletKey);
82
+ walletConnectorCore.walletConnectorEvents.emit('providerInjected', {
83
+ injectedConnectorConstructor,
84
+ });
85
+ };
86
+ const setupSolanaWalletStandardDiscovery = (walletBook, authMode) => {
59
87
  // check to ensure this method doesn't run with SSR
60
88
  if (typeof window === 'undefined') {
61
89
  return;
62
90
  }
63
- removeSolanaWalletStandardListener === null || removeSolanaWalletStandardListener === void 0 ? void 0 : removeSolanaWalletStandardListener();
64
- const { on } = getWalletStandardWallets.getWalletStandardWallets();
65
- removeSolanaWalletStandardListener = on('register', (wallet) => {
66
- var _a, _b;
67
- if (!shouldAddWalletStandardConnector(wallet, walletBook$1, authMode)) {
91
+ teardownSolanaWalletStandardDiscovery === null || teardownSolanaWalletStandardDiscovery === void 0 ? void 0 : teardownSolanaWalletStandardDiscovery();
92
+ // Tracks wallets already surfaced so neither the register listener nor the
93
+ // poll emits a duplicate providerInjected for the same wallet.
94
+ const discoveredWallets = new Set();
95
+ const handleWallet = (wallet) => {
96
+ if (discoveredWallets.has(wallet.name)) {
68
97
  return;
69
98
  }
70
- logger.logger.logVerboseTroubleshootingMessage('[SOL fetchInjectedWalletConnectors] Wallet registered via wallet-standard', wallet.name);
71
- const walletBookWallet = walletBook.findWalletBookWalletByNameAndChain(walletBook$1, wallet.name, 'sol');
72
- const walletKey = walletBookWallet
73
- ? (_b = Object.entries((_a = walletBook$1 === null || walletBook$1 === void 0 ? void 0 : walletBook$1.wallets) !== null && _a !== void 0 ? _a : {}).find(([, entry]) => entry === walletBookWallet)) === null || _b === void 0 ? void 0 : _b[0]
74
- : undefined;
75
- const walletBookMetadata = walletBookWallet &&
76
- walletConnectorCore.getWalletMetadataFromWalletBook({
77
- walletBook: walletBook$1,
78
- walletBookWallet,
79
- walletKey: walletKey !== null && walletKey !== void 0 ? walletKey : `${utils.sanitizeName(wallet.name)}sol`,
80
- });
81
- const injectedConnectorConstructor = getConnectorConstructorForWalletStandardWallet.getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletKey);
82
- walletConnectorCore.walletConnectorEvents.emit('providerInjected', {
83
- injectedConnectorConstructor,
84
- });
99
+ if (!shouldAddWalletStandardConnector(wallet, walletBook, authMode)) {
100
+ return;
101
+ }
102
+ discoveredWallets.add(wallet.name);
103
+ emitWalletStandardConnector(wallet, walletBook);
104
+ };
105
+ const { on, wallets: initialWallets } = getWalletStandardWallets.getWalletStandardWallets();
106
+ // Wallets already present are returned synchronously by
107
+ // fetchInjectedWalletConnectors, so seed them as discovered (no emit needed);
108
+ // the listener and poll then only fire for wallets that appear afterwards.
109
+ initialWallets.forEach((wallet) => {
110
+ if (shouldAddWalletStandardConnector(wallet, walletBook, authMode)) {
111
+ discoveredWallets.add(wallet.name);
112
+ }
85
113
  });
114
+ const removeRegisterListener = on('register', handleWallet);
115
+ const pollForNewWallets = () => {
116
+ getWalletStandardWallets.getWalletStandardWallets().wallets.forEach(handleWallet);
117
+ };
118
+ const pollIntervalId = setInterval(pollForNewWallets, SOLANA_WALLET_STANDARD_POLL_INTERVAL_MS);
119
+ const pollTimeoutId = setTimeout(() => {
120
+ clearInterval(pollIntervalId);
121
+ }, SOLANA_WALLET_STANDARD_POLL_DURATION_MS);
122
+ teardownSolanaWalletStandardDiscovery = () => {
123
+ removeRegisterListener === null || removeRegisterListener === void 0 ? void 0 : removeRegisterListener();
124
+ clearInterval(pollIntervalId);
125
+ clearTimeout(pollTimeoutId);
126
+ };
86
127
  };
87
128
  const fetchInjectedWalletConnectors = ({ walletBook, authMode, }) => {
88
129
  var _a;
89
- addSolanaWalletStandardListener(walletBook, authMode);
130
+ setupSolanaWalletStandardDiscovery(walletBook, authMode);
90
131
  const walletBookConnectors = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {})
91
132
  .filter(([key, wallet]) => {
92
133
  var _a, _b, _c;
@@ -115,6 +156,10 @@ const fetchInjectedWalletConnectors = ({ walletBook, authMode, }) => {
115
156
  walletConnectorCore.getWalletMetadataFromWalletBook({
116
157
  walletBook,
117
158
  walletBookWallet,
159
+ // walletBookKey and walletBookWallet come from the same find() tuple,
160
+ // so walletBookKey is always defined here; the fallback satisfies the
161
+ // typed walletKey but is unreachable at runtime.
162
+ /* istanbul ignore next */
118
163
  walletKey: walletBookKey !== null && walletBookKey !== void 0 ? walletBookKey : `${utils.sanitizeName(wallet.name)}sol`,
119
164
  });
120
165
  return getConnectorConstructorForWalletStandardWallet.getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletBookKey);
@@ -2,6 +2,11 @@ import { WalletBookSchema } from '@dynamic-labs/wallet-book';
2
2
  import { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
3
3
  import type { AuthMode } from '@dynamic-labs/types';
4
4
  export declare const injectedWalletOverrides: WalletConnectorConstructor[];
5
+ /**
6
+ * Stops the active wallet-standard discovery (register listener + poll).
7
+ * @internal - Exposed for test cleanup.
8
+ */
9
+ export declare const stopSolanaWalletStandardDiscovery: () => void;
5
10
  export declare const fetchInjectedWalletConnectors: ({ walletBook, authMode, }: {
6
11
  walletBook: WalletBookSchema;
7
12
  authMode: AuthMode;
@@ -11,7 +11,17 @@ import { getConnectorConstructorForWalletStandardWallet } from './walletStandard
11
11
  import { getWalletStandardWallets } from './walletStandard/getWalletStandardWallets/getWalletStandardWallets.js';
12
12
  import { hasAllWalletStandardRequiredFeatures } from './walletStandard/hasAllWalletStandardRequiredFeatures/hasAllWalletStandardRequiredFeatures.js';
13
13
 
14
- let removeSolanaWalletStandardListener = null;
14
+ /**
15
+ * Teardown for the active wallet-standard discovery (register listener + poll).
16
+ * Recreated on each fetchInjectedWalletConnectors call.
17
+ */
18
+ let teardownSolanaWalletStandardDiscovery = null;
19
+ // Some extensions (e.g. Backpack/Eden/Solflare racing over the page) inject
20
+ // after the initial snapshot, and a one-shot register listener can miss an
21
+ // announcement that fires before we subscribe. Polling the wallet-standard
22
+ // registry for a short window catches those late arrivals without a refresh.
23
+ const SOLANA_WALLET_STANDARD_POLL_INTERVAL_MS = 300;
24
+ const SOLANA_WALLET_STANDARD_POLL_DURATION_MS = 5000;
15
25
  const injectedWalletOverrides = [
16
26
  CoinbaseSolana,
17
27
  BackpackSol,
@@ -51,38 +61,69 @@ const shouldAddWalletStandardConnector = (wallet, walletBook, authMode) => {
51
61
  });
52
62
  return !shouldHandleFromWalletBook && hasAllFeatures;
53
63
  };
54
- const addSolanaWalletStandardListener = (walletBook, authMode) => {
64
+ const emitWalletStandardConnector = (wallet, walletBook) => {
65
+ var _a, _b;
66
+ logger.logVerboseTroubleshootingMessage('[SOL fetchInjectedWalletConnectors] Emitting providerInjected for wallet-standard wallet', wallet.name);
67
+ const walletBookWallet = findWalletBookWalletByNameAndChain(walletBook, wallet.name, 'sol');
68
+ const walletKey = walletBookWallet
69
+ ? (_b = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {}).find(([, entry]) => entry === walletBookWallet)) === null || _b === void 0 ? void 0 : _b[0]
70
+ : undefined;
71
+ const walletBookMetadata = walletBookWallet &&
72
+ getWalletMetadataFromWalletBook({
73
+ walletBook,
74
+ walletBookWallet,
75
+ walletKey: walletKey !== null && walletKey !== void 0 ? walletKey : `${sanitizeName(wallet.name)}sol`,
76
+ });
77
+ const injectedConnectorConstructor = getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletKey);
78
+ walletConnectorEvents.emit('providerInjected', {
79
+ injectedConnectorConstructor,
80
+ });
81
+ };
82
+ const setupSolanaWalletStandardDiscovery = (walletBook, authMode) => {
55
83
  // check to ensure this method doesn't run with SSR
56
84
  if (typeof window === 'undefined') {
57
85
  return;
58
86
  }
59
- removeSolanaWalletStandardListener === null || removeSolanaWalletStandardListener === void 0 ? void 0 : removeSolanaWalletStandardListener();
60
- const { on } = getWalletStandardWallets();
61
- removeSolanaWalletStandardListener = on('register', (wallet) => {
62
- var _a, _b;
87
+ teardownSolanaWalletStandardDiscovery === null || teardownSolanaWalletStandardDiscovery === void 0 ? void 0 : teardownSolanaWalletStandardDiscovery();
88
+ // Tracks wallets already surfaced so neither the register listener nor the
89
+ // poll emits a duplicate providerInjected for the same wallet.
90
+ const discoveredWallets = new Set();
91
+ const handleWallet = (wallet) => {
92
+ if (discoveredWallets.has(wallet.name)) {
93
+ return;
94
+ }
63
95
  if (!shouldAddWalletStandardConnector(wallet, walletBook, authMode)) {
64
96
  return;
65
97
  }
66
- logger.logVerboseTroubleshootingMessage('[SOL fetchInjectedWalletConnectors] Wallet registered via wallet-standard', wallet.name);
67
- const walletBookWallet = findWalletBookWalletByNameAndChain(walletBook, wallet.name, 'sol');
68
- const walletKey = walletBookWallet
69
- ? (_b = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {}).find(([, entry]) => entry === walletBookWallet)) === null || _b === void 0 ? void 0 : _b[0]
70
- : undefined;
71
- const walletBookMetadata = walletBookWallet &&
72
- getWalletMetadataFromWalletBook({
73
- walletBook,
74
- walletBookWallet,
75
- walletKey: walletKey !== null && walletKey !== void 0 ? walletKey : `${sanitizeName(wallet.name)}sol`,
76
- });
77
- const injectedConnectorConstructor = getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletKey);
78
- walletConnectorEvents.emit('providerInjected', {
79
- injectedConnectorConstructor,
80
- });
98
+ discoveredWallets.add(wallet.name);
99
+ emitWalletStandardConnector(wallet, walletBook);
100
+ };
101
+ const { on, wallets: initialWallets } = getWalletStandardWallets();
102
+ // Wallets already present are returned synchronously by
103
+ // fetchInjectedWalletConnectors, so seed them as discovered (no emit needed);
104
+ // the listener and poll then only fire for wallets that appear afterwards.
105
+ initialWallets.forEach((wallet) => {
106
+ if (shouldAddWalletStandardConnector(wallet, walletBook, authMode)) {
107
+ discoveredWallets.add(wallet.name);
108
+ }
81
109
  });
110
+ const removeRegisterListener = on('register', handleWallet);
111
+ const pollForNewWallets = () => {
112
+ getWalletStandardWallets().wallets.forEach(handleWallet);
113
+ };
114
+ const pollIntervalId = setInterval(pollForNewWallets, SOLANA_WALLET_STANDARD_POLL_INTERVAL_MS);
115
+ const pollTimeoutId = setTimeout(() => {
116
+ clearInterval(pollIntervalId);
117
+ }, SOLANA_WALLET_STANDARD_POLL_DURATION_MS);
118
+ teardownSolanaWalletStandardDiscovery = () => {
119
+ removeRegisterListener === null || removeRegisterListener === void 0 ? void 0 : removeRegisterListener();
120
+ clearInterval(pollIntervalId);
121
+ clearTimeout(pollTimeoutId);
122
+ };
82
123
  };
83
124
  const fetchInjectedWalletConnectors = ({ walletBook, authMode, }) => {
84
125
  var _a;
85
- addSolanaWalletStandardListener(walletBook, authMode);
126
+ setupSolanaWalletStandardDiscovery(walletBook, authMode);
86
127
  const walletBookConnectors = Object.entries((_a = walletBook === null || walletBook === void 0 ? void 0 : walletBook.wallets) !== null && _a !== void 0 ? _a : {})
87
128
  .filter(([key, wallet]) => {
88
129
  var _a, _b, _c;
@@ -111,6 +152,10 @@ const fetchInjectedWalletConnectors = ({ walletBook, authMode, }) => {
111
152
  getWalletMetadataFromWalletBook({
112
153
  walletBook,
113
154
  walletBookWallet,
155
+ // walletBookKey and walletBookWallet come from the same find() tuple,
156
+ // so walletBookKey is always defined here; the fallback satisfies the
157
+ // typed walletKey but is unreachable at runtime.
158
+ /* istanbul ignore next */
114
159
  walletKey: walletBookKey !== null && walletBookKey !== void 0 ? walletBookKey : `${sanitizeName(wallet.name)}sol`,
115
160
  });
116
161
  return getConnectorConstructorForWalletStandardWallet(wallet, walletBookMetadata, walletBookKey);