@dynamic-labs/solana 5.0.0-rc.0 → 5.0.0-rc.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,5 +1,76 @@
1
1
 
2
- ## [5.0.0-rc.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.6...v5.0.0-rc.0) (2026-07-05)
2
+ ## [5.0.0-rc.1](https://github.com/dynamic-labs/dynamic-auth/compare/v5.0.0-rc.0...v5.0.0-rc.1) (2026-07-17)
3
+
4
+
5
+ ### ⚠ BREAKING CHANGES
6
+
7
+ * move legacy embedded wallet to waas upgrade flow to new legacy-embedded-wallet-migration package (#11841)
8
+ * drop default injection of legacy embedded wallet connectors (#11833)
9
+ * remove legacy embedded wallet support (#11979)
10
+ * throw when legacy embedded wallet is detected without migration provider (#11855)
11
+ * remove deprecated eclipse package (#11831)
12
+ * remove deprecated functions and props (#11832)
13
+
14
+
15
+ ### [4.92.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.3...v4.92.4) (2026-07-16)
16
+
17
+
18
+ ### Features
19
+
20
+ * **bitcoin:** per-network address switching and dust-limit send validation [v4] ([#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970)) ([76a4a9a](https://github.com/dynamic-labs/dynamic-auth/commit/76a4a9a5025d78798ebd1beffe6c0af59d2d029a)), closes [#11896](https://github.com/dynamic-labs/dynamic-auth/issues/11896) [#11800](https://github.com/dynamic-labs/dynamic-auth/issues/11800)
21
+ * **midnight:** per-network addresses in deposit and wallet info views [v4] ([#11949](https://github.com/dynamic-labs/dynamic-auth/issues/11949)) ([978446a](https://github.com/dynamic-labs/dynamic-auth/commit/978446aca8546eb038ba9ed3be0503d10594ee15))
22
+ * **midnight:** resolve wallet address per selected network [v4] ([#11948](https://github.com/dynamic-labs/dynamic-auth/issues/11948)) ([d6f858c](https://github.com/dynamic-labs/dynamic-auth/commit/d6f858c5e35defda7ed73cf97b3fdbe5ed9d131d))
23
+ * set useMetamaskSdk to true by default ([#11926](https://github.com/dynamic-labs/dynamic-auth/issues/11926)) ([75b5a4a](https://github.com/dynamic-labs/dynamic-auth/commit/75b5a4a0fe8b1a375afce145c0b8bdc3ce761117))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **midnight:** align per-network code with the final main iteration [v4] ([#11971](https://github.com/dynamic-labs/dynamic-auth/issues/11971)) ([3ef3ba8](https://github.com/dynamic-labs/dynamic-auth/commit/3ef3ba8c090dfd9e4286b4e51bf350ea5e6feac7))
29
+ * settle social sign-in when captcha is backed out or oauth popup never responds (v4) ([#11956](https://github.com/dynamic-labs/dynamic-auth/issues/11956)) ([ad49477](https://github.com/dynamic-labs/dynamic-auth/commit/ad49477f2acf61a154bb79cbe26b24f803cdb0e2))
30
+ * validate that private key is not empty before upgrading to WaaS ([#11952](https://github.com/dynamic-labs/dynamic-auth/issues/11952)) ([21dfb83](https://github.com/dynamic-labs/dynamic-auth/commit/21dfb83cb29e42b335bc94a0cdd2062cf14a262a))
31
+
32
+ ### [4.92.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.2...v4.92.3) (2026-07-10)
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * **sdk-react-core:** fix deterministic 'Wallet not found' crash in embedded wallet export (v4) ([#11906](https://github.com/dynamic-labs/dynamic-auth/issues/11906)) ([913ef23](https://github.com/dynamic-labs/dynamic-auth/commit/913ef236b26245488e1cd5db7e874601b65ff0a2)), closes [#11905](https://github.com/dynamic-labs/dynamic-auth/issues/11905) [#11729](https://github.com/dynamic-labs/dynamic-auth/issues/11729)
38
+
39
+ ### [4.92.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.1...v4.92.2) (2026-07-09)
40
+
41
+
42
+ ### Bug Fixes
43
+
44
+ * engage captcha during step-up OTP re-auth ([#11879](https://github.com/dynamic-labs/dynamic-auth/issues/11879)) ([585460a](https://github.com/dynamic-labs/dynamic-auth/commit/585460a8976803a8ed0aad16a4a00047bd6c115a))
45
+ * **waas:** gate v1 wallet upgrade on recovery for email-only wallets ([#11897](https://github.com/dynamic-labs/dynamic-auth/issues/11897)) ([5a6f0c6](https://github.com/dynamic-labs/dynamic-auth/commit/5a6f0c6bf3120e59cf502004d09fae56f193e977))
46
+
47
+ ### [4.92.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.0...v4.92.1) (2026-07-09)
48
+
49
+
50
+ ### Bug Fixes
51
+
52
+ * **ethereum:** fire in-app-browser redirect on sign for injected EVM wallets that use in-app-browser experience ([#11888](https://github.com/dynamic-labs/dynamic-auth/issues/11888)) ([5116d91](https://github.com/dynamic-labs/dynamic-auth/commit/5116d91ab2c71000a490d72c5d278549d4d8ae9a))
53
+ * **sdk-react-core:** show clear message for Phantom redirect signing failures (v4 backport) ([#11886](https://github.com/dynamic-labs/dynamic-auth/issues/11886)) ([60ac897](https://github.com/dynamic-labs/dynamic-auth/commit/60ac897ba81f7758ccd7a05f97b619785e1f50a7))
54
+ * **social:** use redirect strategy for step-up OAuth on mobile [V4 backport] ([#11881](https://github.com/dynamic-labs/dynamic-auth/issues/11881)) ([42a202e](https://github.com/dynamic-labs/dynamic-auth/commit/42a202e6255de8db73df02eff37c0b10b24fef1a))
55
+ * **solana:** fire in-app-browser redirect on sign and wallet switch ([#11871](https://github.com/dynamic-labs/dynamic-auth/issues/11871)) ([4e2d6b7](https://github.com/dynamic-labs/dynamic-auth/commit/4e2d6b7ac8fdef5bf7c62b8a726ecaef1c6210ec))
56
+ * **solana:** resolve Phantom/Backpack provider collision and Backpack >=0.10.x connect hangs ([#11856](https://github.com/dynamic-labs/dynamic-auth/issues/11856)) ([#11882](https://github.com/dynamic-labs/dynamic-auth/issues/11882)) ([5784aff](https://github.com/dynamic-labs/dynamic-auth/commit/5784aff9641bbc85445fb466f3ab1d6a14331e73))
57
+
58
+ ## [4.92.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.6...v4.92.0) (2026-07-08)
59
+
60
+
61
+ ### Features
62
+
63
+ * **captcha:** add Cloudflare Turnstile provider support alongside hCaptcha (v4) ([#11798](https://github.com/dynamic-labs/dynamic-auth/issues/11798)) ([114c770](https://github.com/dynamic-labs/dynamic-auth/commit/114c7702e900d8dedeebe7be867de35d11a93f31))
64
+
65
+
66
+ ### Bug Fixes
67
+
68
+ * **ethereum-aa:** resolve kernel client config per wallet (v4) ([#11870](https://github.com/dynamic-labs/dynamic-auth/issues/11870)) ([1b66d79](https://github.com/dynamic-labs/dynamic-auth/commit/1b66d79b4a32b4b6de433b7536bc46e6719224c6))
69
+ * **iframe-setup:** block dangerous URL schemes and verify sender in OPEN_URL ([#11819](https://github.com/dynamic-labs/dynamic-auth/issues/11819)) ([329b27e](https://github.com/dynamic-labs/dynamic-auth/commit/329b27e9fac825916ab227ec8cf93dc343898923))
70
+ * improve social OAuth error messages ([#11837](https://github.com/dynamic-labs/dynamic-auth/issues/11837)) ([8e57c06](https://github.com/dynamic-labs/dynamic-auth/commit/8e57c067c5a89111a32a12fb82e190cf6c46ad67))
71
+ * **react-native-extension:** reject path traversal in downloadFile fileName ([#11816](https://github.com/dynamic-labs/dynamic-auth/issues/11816)) ([9367a56](https://github.com/dynamic-labs/dynamic-auth/commit/9367a56b6daa853d7f7e7f5534261bc68825b239))
72
+ * **sdk-react-core:** display exactly the bytes signed in personal_sign preview ([#11818](https://github.com/dynamic-labs/dynamic-auth/issues/11818)) ([30b9382](https://github.com/dynamic-labs/dynamic-auth/commit/30b93829122f00060cb484aef09a03294c03f651))
73
+
3
74
 
4
75
  ### [4.91.6](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.5...v4.91.6) (2026-07-03)
5
76
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "5.0.0-rc.0";
6
+ var version = "5.0.0-rc.1";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "5.0.0-rc.0";
2
+ var version = "5.0.0-rc.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": "5.0.0-rc.0",
3
+ "version": "5.0.0-rc.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,8 +18,8 @@
18
18
  },
19
19
  "homepage": "https://www.dynamic.xyz/",
20
20
  "dependencies": {
21
- "@dynamic-labs/wallet-connect": "5.0.0-rc.0",
22
- "@dynamic-labs-connectors/metamask-solana": "4.6.10",
21
+ "@dynamic-labs/wallet-connect": "5.0.0-rc.1",
22
+ "@dynamic-labs-connectors/metamask-solana": "4.6.15",
23
23
  "@solana/web3.js": "1.98.1",
24
24
  "@wallet-standard/app": "1.0.1",
25
25
  "@wallet-standard/base": "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": "5.0.0-rc.0",
34
- "@dynamic-labs/embedded-wallet-solana": "5.0.0-rc.0",
35
- "@dynamic-labs/logger": "5.0.0-rc.0",
36
- "@dynamic-labs/rpc-providers": "5.0.0-rc.0",
37
- "@dynamic-labs/sdk-api-core": "0.0.1046",
38
- "@dynamic-labs/solana-core": "5.0.0-rc.0",
39
- "@dynamic-labs/types": "5.0.0-rc.0",
40
- "@dynamic-labs/utils": "5.0.0-rc.0",
41
- "@dynamic-labs/waas-svm": "5.0.0-rc.0",
42
- "@dynamic-labs/wallet-book": "5.0.0-rc.0",
43
- "@dynamic-labs/wallet-connector-core": "5.0.0-rc.0",
33
+ "@dynamic-labs/assert-package-version": "5.0.0-rc.1",
34
+ "@dynamic-labs/embedded-wallet-solana": "5.0.0-rc.1",
35
+ "@dynamic-labs/logger": "5.0.0-rc.1",
36
+ "@dynamic-labs/rpc-providers": "5.0.0-rc.1",
37
+ "@dynamic-labs/sdk-api-core": "0.0.1082",
38
+ "@dynamic-labs/solana-core": "5.0.0-rc.1",
39
+ "@dynamic-labs/types": "5.0.0-rc.1",
40
+ "@dynamic-labs/utils": "5.0.0-rc.1",
41
+ "@dynamic-labs/waas-svm": "5.0.0-rc.1",
42
+ "@dynamic-labs/wallet-book": "5.0.0-rc.1",
43
+ "@dynamic-labs/wallet-connector-core": "5.0.0-rc.1",
44
44
  "eventemitter3": "5.0.1"
45
45
  },
46
46
  "peerDependencies": {}
@@ -15,9 +15,11 @@ class CoinbaseSolana extends InjectedWalletBase.InjectedWalletBase {
15
15
  this.overrideKey = 'coinbasesolana';
16
16
  }
17
17
  getSigner() {
18
+ const _super = Object.create(null, {
19
+ getSigner: { get: () => super.getSigner }
20
+ });
18
21
  return _tslib.__awaiter(this, void 0, void 0, function* () {
19
- var _a;
20
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
22
+ return _super.getSigner.call(this);
21
23
  });
22
24
  }
23
25
  signMessage(messageToSign) {
@@ -1,7 +1,8 @@
1
+ import { ISolanaSigner } from '@dynamic-labs/solana-core';
1
2
  import { InjectedWalletBase } from '../injected/InjectedWalletBase';
2
3
  export declare class CoinbaseSolana extends InjectedWalletBase {
3
4
  name: string;
4
5
  overrideKey: string;
5
- getSigner<ICoinbaseSolanaSigner>(): Promise<ICoinbaseSolanaSigner | undefined>;
6
+ getSigner<T = ISolanaSigner>(): Promise<T | undefined>;
6
7
  signMessage(messageToSign: string): Promise<string | undefined>;
7
8
  }
@@ -11,9 +11,11 @@ class CoinbaseSolana extends InjectedWalletBase {
11
11
  this.overrideKey = 'coinbasesolana';
12
12
  }
13
13
  getSigner() {
14
+ const _super = Object.create(null, {
15
+ getSigner: { get: () => super.getSigner }
16
+ });
14
17
  return __awaiter(this, void 0, void 0, function* () {
15
- var _a;
16
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
18
+ return _super.getSigner.call(this);
17
19
  });
18
20
  }
19
21
  signMessage(messageToSign) {
@@ -10,6 +10,11 @@ var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
10
10
  var findWalletProviderFromWalletStandard = require('../injected/walletStandard/findWalletProviderFromWalletStandard/findWalletProviderFromWalletStandard.cjs');
11
11
  var isSignedMessage = require('../utils/isSignedMessage.cjs');
12
12
 
13
+ // Some providers (e.g. Backpack) never settle a connect({ onlyIfTrusted:
14
+ // true }) probe for an origin the user hasn't approved yet. Since
15
+ // getConnectedAccounts gates the connect-and-sign flow, an unresolved probe
16
+ // would freeze the whole flow, so it is capped with a timeout.
17
+ const TRUSTED_CONNECT_TIMEOUT_MS = 3000;
13
18
  class SolProviderHelper {
14
19
  constructor(connector) {
15
20
  this.walletBookWallet = walletBook.findWalletBookWallet(connector.walletBook, connector.key);
@@ -33,6 +38,18 @@ class SolProviderHelper {
33
38
  if (!config)
34
39
  return [];
35
40
  const providers = [];
41
+ // Wallet Standard providers are checked first because they are
42
+ // identified by a unique wallet name in the registry, making them
43
+ // the most reliable source. Legacy window-object lookups
44
+ // (window.phantom.solana, window.solana) are susceptible to being
45
+ // hijacked or proxied by other extensions (e.g. Backpack overriding
46
+ // window.solana with isPhantom=true), so they come after.
47
+ if (((_b = (_a = config.walletStandardLocators) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
48
+ const walletStandardProvider = findWalletProviderFromWalletStandard.findWalletProviderFromWalletStandard(config);
49
+ if (walletStandardProvider) {
50
+ providers.push(walletStandardProvider);
51
+ }
52
+ }
36
53
  if (config.windowLocations) {
37
54
  for (const windowLocation of config.windowLocations) {
38
55
  const foundProviders = utils.getProvidersFromWindow(windowLocation);
@@ -51,12 +68,6 @@ class SolProviderHelper {
51
68
  window.solana.providers.forEach((provider) => providers.push(provider));
52
69
  }
53
70
  }
54
- if (((_b = (_a = config.walletStandardLocators) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
55
- const walletStandardProvider = findWalletProviderFromWalletStandard.findWalletProviderFromWalletStandard(config);
56
- if (walletStandardProvider) {
57
- providers.push(walletStandardProvider);
58
- }
59
- }
60
71
  return providers;
61
72
  }
62
73
  installedProviderLookup(extensionLocators) {
@@ -174,7 +185,7 @@ class SolProviderHelper {
174
185
  let connectionResult;
175
186
  try {
176
187
  if (!provider.isConnected) {
177
- connectionResult = yield provider.connect({ onlyIfTrusted: true });
188
+ connectionResult = yield utils.promiseWithTimeout(Promise.resolve(provider.connect({ onlyIfTrusted: true })), TRUSTED_CONNECT_TIMEOUT_MS);
178
189
  }
179
190
  }
180
191
  catch (e) {
@@ -24,7 +24,7 @@ export declare class SolProviderHelper {
24
24
  windowLocations?: string[] | undefined;
25
25
  } | undefined;
26
26
  getInstalledProvider(): ISolana | undefined;
27
- installedProviders(): import("@dynamic-labs/solana-core").ISolanaSigner[];
27
+ installedProviders(): ISolana[];
28
28
  installedProviderLookup(extensionLocators: Array<ProviderCondition<ExtensionLocator>>): ISolana | undefined;
29
29
  findProvider(): ISolana | undefined;
30
30
  isInstalledHelper(): boolean;
@@ -1,11 +1,16 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../_virtual/_tslib.js';
3
- import { getProvidersFromWindow, bufferToBase64 } from '@dynamic-labs/utils';
3
+ import { getProvidersFromWindow, bufferToBase64, promiseWithTimeout } from '@dynamic-labs/utils';
4
4
  import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
5
5
  import { ProviderLookup, logger } from '@dynamic-labs/wallet-connector-core';
6
6
  import { findWalletProviderFromWalletStandard } from '../injected/walletStandard/findWalletProviderFromWalletStandard/findWalletProviderFromWalletStandard.js';
7
7
  import { isSignedMessage } from '../utils/isSignedMessage.js';
8
8
 
9
+ // Some providers (e.g. Backpack) never settle a connect({ onlyIfTrusted:
10
+ // true }) probe for an origin the user hasn't approved yet. Since
11
+ // getConnectedAccounts gates the connect-and-sign flow, an unresolved probe
12
+ // would freeze the whole flow, so it is capped with a timeout.
13
+ const TRUSTED_CONNECT_TIMEOUT_MS = 3000;
9
14
  class SolProviderHelper {
10
15
  constructor(connector) {
11
16
  this.walletBookWallet = findWalletBookWallet(connector.walletBook, connector.key);
@@ -29,6 +34,18 @@ class SolProviderHelper {
29
34
  if (!config)
30
35
  return [];
31
36
  const providers = [];
37
+ // Wallet Standard providers are checked first because they are
38
+ // identified by a unique wallet name in the registry, making them
39
+ // the most reliable source. Legacy window-object lookups
40
+ // (window.phantom.solana, window.solana) are susceptible to being
41
+ // hijacked or proxied by other extensions (e.g. Backpack overriding
42
+ // window.solana with isPhantom=true), so they come after.
43
+ if (((_b = (_a = config.walletStandardLocators) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
44
+ const walletStandardProvider = findWalletProviderFromWalletStandard(config);
45
+ if (walletStandardProvider) {
46
+ providers.push(walletStandardProvider);
47
+ }
48
+ }
32
49
  if (config.windowLocations) {
33
50
  for (const windowLocation of config.windowLocations) {
34
51
  const foundProviders = getProvidersFromWindow(windowLocation);
@@ -47,12 +64,6 @@ class SolProviderHelper {
47
64
  window.solana.providers.forEach((provider) => providers.push(provider));
48
65
  }
49
66
  }
50
- if (((_b = (_a = config.walletStandardLocators) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
51
- const walletStandardProvider = findWalletProviderFromWalletStandard(config);
52
- if (walletStandardProvider) {
53
- providers.push(walletStandardProvider);
54
- }
55
- }
56
67
  return providers;
57
68
  }
58
69
  installedProviderLookup(extensionLocators) {
@@ -170,7 +181,7 @@ class SolProviderHelper {
170
181
  let connectionResult;
171
182
  try {
172
183
  if (!provider.isConnected) {
173
- connectionResult = yield provider.connect({ onlyIfTrusted: true });
184
+ connectionResult = yield promiseWithTimeout(Promise.resolve(provider.connect({ onlyIfTrusted: true })), TRUSTED_CONNECT_TIMEOUT_MS);
174
185
  }
175
186
  }
176
187
  catch (e) {
@@ -4,7 +4,6 @@
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var metamaskSolana = require('@dynamic-labs-connectors/metamask-solana');
7
- var embeddedWalletSolana = require('@dynamic-labs/embedded-wallet-solana');
8
7
  var waasSvm = require('@dynamic-labs/waas-svm');
9
8
  var Phantom = require('./Phantom/Phantom.cjs');
10
9
  var fetchInjectedWalletConnectors = require('./injected/fetchInjectedWalletConnectors.cjs');
@@ -25,7 +24,6 @@ props) => {
25
24
  const initialConnectors = [
26
25
  ...fetchInjectedWalletConnectors.injectedWalletOverrides,
27
26
  ...fetchInjectedWalletConnectors.fetchInjectedWalletConnectors(props),
28
- ...embeddedWalletSolana.TurnkeySolanaWalletConnectors(props),
29
27
  ...waasSvm.DynamicWaasSVMConnectors(),
30
28
  ...metamaskSolana.MetaMaskSolanaWalletConnectors(props),
31
29
  Phantom.Phantom,
@@ -1,6 +1,5 @@
1
1
  'use client'
2
2
  import { MetaMaskSolanaWalletConnectors } from '@dynamic-labs-connectors/metamask-solana';
3
- import { TurnkeySolanaWalletConnectors } from '@dynamic-labs/embedded-wallet-solana';
4
3
  import { DynamicWaasSVMConnectors } from '@dynamic-labs/waas-svm';
5
4
  import { Phantom } from './Phantom/Phantom.js';
6
5
  import { injectedWalletOverrides, fetchInjectedWalletConnectors } from './injected/fetchInjectedWalletConnectors.js';
@@ -21,7 +20,6 @@ props) => {
21
20
  const initialConnectors = [
22
21
  ...injectedWalletOverrides,
23
22
  ...fetchInjectedWalletConnectors(props),
24
- ...TurnkeySolanaWalletConnectors(props),
25
23
  ...DynamicWaasSVMConnectors(),
26
24
  ...MetaMaskSolanaWalletConnectors(props),
27
25
  Phantom,
@@ -20,23 +20,21 @@ class Solflare extends InjectedWalletBase.InjectedWalletBase {
20
20
  // so always return the injected connector
21
21
  return this;
22
22
  }
23
- getAddress() {
24
- return _tslib.__awaiter(this, void 0, void 0, function* () {
25
- var _a, _b;
26
- /**
27
- * It should redirect to in-app browser if on mobile and if not in the in-app browser,
28
- * this checks if it is not in the in-app browser by checking if the provider is not available.
29
- */
30
- if (utils.isMobile() && !this.isInstalledOnBrowser()) {
31
- const mobileDeepLinks = (_a = this.metadata.deepLinks) === null || _a === void 0 ? void 0 : _a.mobile;
32
- utils.handleMobileWalletRedirect({
33
- nativeLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.native) || 'solflare://ul/v1/browse',
34
- universalLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.universal) || 'https://solflare.com/ul/v1/browse',
35
- });
36
- return;
37
- }
38
- return (_b = this.solProviderHelper) === null || _b === void 0 ? void 0 : _b.getAddress();
39
- });
23
+ /**
24
+ * It should redirect to in-app browser if on mobile and if not in the in-app browser,
25
+ * this checks if it is not in the in-app browser by checking if the provider is not available.
26
+ */
27
+ openInAppBrowserIfRequired() {
28
+ var _a;
29
+ if (utils.isMobile() && !this.isInstalledOnBrowser()) {
30
+ const mobileDeepLinks = (_a = this.metadata.deepLinks) === null || _a === void 0 ? void 0 : _a.mobile;
31
+ utils.handleMobileWalletRedirect({
32
+ nativeLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.native) || 'solflare://ul/v1/browse',
33
+ universalLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.universal) || 'https://solflare.com/ul/v1/browse',
34
+ });
35
+ return true;
36
+ }
37
+ return false;
40
38
  }
41
39
  signMessage(messageToSign) {
42
40
  return _tslib.__awaiter(this, void 0, void 0, function* () {
@@ -5,6 +5,10 @@ export declare class Solflare extends InjectedWalletBase {
5
5
  overrideKey: string;
6
6
  constructor(props: SolanaWalletConnectorOpts);
7
7
  getMobileOrInstalledWallet(): InjectedWalletBase;
8
- getAddress(): Promise<string | undefined>;
8
+ /**
9
+ * It should redirect to in-app browser if on mobile and if not in the in-app browser,
10
+ * this checks if it is not in the in-app browser by checking if the provider is not available.
11
+ */
12
+ openInAppBrowserIfRequired(): boolean;
9
13
  signMessage(messageToSign: string): Promise<string | undefined>;
10
14
  }
@@ -16,23 +16,21 @@ class Solflare extends InjectedWalletBase {
16
16
  // so always return the injected connector
17
17
  return this;
18
18
  }
19
- getAddress() {
20
- return __awaiter(this, void 0, void 0, function* () {
21
- var _a, _b;
22
- /**
23
- * It should redirect to in-app browser if on mobile and if not in the in-app browser,
24
- * this checks if it is not in the in-app browser by checking if the provider is not available.
25
- */
26
- if (isMobile() && !this.isInstalledOnBrowser()) {
27
- const mobileDeepLinks = (_a = this.metadata.deepLinks) === null || _a === void 0 ? void 0 : _a.mobile;
28
- handleMobileWalletRedirect({
29
- nativeLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.native) || 'solflare://ul/v1/browse',
30
- universalLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.universal) || 'https://solflare.com/ul/v1/browse',
31
- });
32
- return;
33
- }
34
- return (_b = this.solProviderHelper) === null || _b === void 0 ? void 0 : _b.getAddress();
35
- });
19
+ /**
20
+ * It should redirect to in-app browser if on mobile and if not in the in-app browser,
21
+ * this checks if it is not in the in-app browser by checking if the provider is not available.
22
+ */
23
+ openInAppBrowserIfRequired() {
24
+ var _a;
25
+ if (isMobile() && !this.isInstalledOnBrowser()) {
26
+ const mobileDeepLinks = (_a = this.metadata.deepLinks) === null || _a === void 0 ? void 0 : _a.mobile;
27
+ handleMobileWalletRedirect({
28
+ nativeLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.native) || 'solflare://ul/v1/browse',
29
+ universalLink: (mobileDeepLinks === null || mobileDeepLinks === void 0 ? void 0 : mobileDeepLinks.universal) || 'https://solflare.com/ul/v1/browse',
30
+ });
31
+ return true;
32
+ }
33
+ return false;
36
34
  }
37
35
  signMessage(messageToSign) {
38
36
  return __awaiter(this, void 0, void 0, function* () {
@@ -16,9 +16,40 @@ class BackpackSol extends InjectedWalletBase.InjectedWalletBase {
16
16
  this.walletConnectWalletBookEntry = walletBook.findWalletBookWallet(props.walletBook, this.key);
17
17
  }
18
18
  getSigner() {
19
+ const _super = Object.create(null, {
20
+ getSigner: { get: () => super.getSigner }
21
+ });
22
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
23
+ return _super.getSigner.call(this);
24
+ });
25
+ }
26
+ // Backpack >= 0.10.x turned window.backpack into a multichain namespace
27
+ // whose top-level connect() never resolves; the live Solana provider is
28
+ // nested at window.backpack.solana. The wallet book served from the CDN may
29
+ // still locate the namespace via windowLocations ["backpack"], so prefer
30
+ // the nested provider whenever it is present.
31
+ findProvider() {
32
+ const [nestedProvider] = utils.getProvidersFromWindow('backpack.solana');
33
+ if (nestedProvider === null || nestedProvider === void 0 ? void 0 : nestedProvider.isBackpack) {
34
+ return nestedProvider;
35
+ }
36
+ return super.findProvider();
37
+ }
38
+ // Backpack treats connect({ onlyIfTrusted: true }) as a full connect: it
39
+ // queues the request and opens its approval popup, and it drops any
40
+ // subsequent connect() issued while that request is pending. Probing it
41
+ // like the base implementation does would therefore deadlock the real
42
+ // connect that follows, so only report accounts for an already-connected
43
+ // provider.
44
+ getConnectedAccounts() {
19
45
  return _tslib.__awaiter(this, void 0, void 0, function* () {
20
46
  var _a;
21
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
47
+ const provider = this.findProvider();
48
+ if (!(provider === null || provider === void 0 ? void 0 : provider.isConnected)) {
49
+ return [];
50
+ }
51
+ const publicKey = (_a = provider.publicKey) === null || _a === void 0 ? void 0 : _a.toString();
52
+ return publicKey ? [publicKey] : [];
22
53
  });
23
54
  }
24
55
  signMessage(messageToSign) {
@@ -1,9 +1,11 @@
1
- import { SolanaWalletConnectorOpts } from '@dynamic-labs/solana-core';
1
+ import { SolanaWalletConnectorOpts, type IBackpackSolanaSigner, type ISolana } from '@dynamic-labs/solana-core';
2
2
  import { InjectedWalletBase } from '../InjectedWalletBase';
3
3
  export declare class BackpackSol extends InjectedWalletBase {
4
4
  name: string;
5
5
  overrideKey: string;
6
6
  constructor(props: SolanaWalletConnectorOpts);
7
- getSigner<IBackpackSolanaSigner>(): Promise<IBackpackSolanaSigner | undefined>;
7
+ getSigner<T = IBackpackSolanaSigner>(): Promise<T | undefined>;
8
+ findProvider(): ISolana | undefined;
9
+ getConnectedAccounts(): Promise<string[]>;
8
10
  signMessage(messageToSign: string): Promise<string | undefined>;
9
11
  }
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../_virtual/_tslib.js';
3
- import { bufferToBase64 } from '@dynamic-labs/utils';
3
+ import { getProvidersFromWindow, bufferToBase64 } from '@dynamic-labs/utils';
4
4
  import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
5
5
  import { InjectedWalletBase } from '../InjectedWalletBase/InjectedWalletBase.js';
6
6
 
@@ -12,9 +12,40 @@ class BackpackSol extends InjectedWalletBase {
12
12
  this.walletConnectWalletBookEntry = findWalletBookWallet(props.walletBook, this.key);
13
13
  }
14
14
  getSigner() {
15
+ const _super = Object.create(null, {
16
+ getSigner: { get: () => super.getSigner }
17
+ });
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ return _super.getSigner.call(this);
20
+ });
21
+ }
22
+ // Backpack >= 0.10.x turned window.backpack into a multichain namespace
23
+ // whose top-level connect() never resolves; the live Solana provider is
24
+ // nested at window.backpack.solana. The wallet book served from the CDN may
25
+ // still locate the namespace via windowLocations ["backpack"], so prefer
26
+ // the nested provider whenever it is present.
27
+ findProvider() {
28
+ const [nestedProvider] = getProvidersFromWindow('backpack.solana');
29
+ if (nestedProvider === null || nestedProvider === void 0 ? void 0 : nestedProvider.isBackpack) {
30
+ return nestedProvider;
31
+ }
32
+ return super.findProvider();
33
+ }
34
+ // Backpack treats connect({ onlyIfTrusted: true }) as a full connect: it
35
+ // queues the request and opens its approval popup, and it drops any
36
+ // subsequent connect() issued while that request is pending. Probing it
37
+ // like the base implementation does would therefore deadlock the real
38
+ // connect that follows, so only report accounts for an already-connected
39
+ // provider.
40
+ getConnectedAccounts() {
15
41
  return __awaiter(this, void 0, void 0, function* () {
16
42
  var _a;
17
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
43
+ const provider = this.findProvider();
44
+ if (!(provider === null || provider === void 0 ? void 0 : provider.isConnected)) {
45
+ return [];
46
+ }
47
+ const publicKey = (_a = provider.publicKey) === null || _a === void 0 ? void 0 : _a.toString();
48
+ return publicKey ? [publicKey] : [];
18
49
  });
19
50
  }
20
51
  signMessage(messageToSign) {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
6
6
  var _tslib = require('../../../_virtual/_tslib.cjs');
7
7
  var web3_js = require('@solana/web3.js');
8
8
  var solanaCore = require('@dynamic-labs/solana-core');
9
+ var utils = require('@dynamic-labs/utils');
9
10
  var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
10
11
  var SolProviderHelper = require('../../SolProviderHelper/SolProviderHelper.cjs');
11
12
  var SignMessageNotSupportedError = require('../../errors/SignMessageNotSupportedError.cjs');
@@ -67,7 +68,21 @@ class InjectedWalletBase extends solanaCore.SolanaWalletConnector {
67
68
  getSigner() {
68
69
  return _tslib.__awaiter(this, void 0, void 0, function* () {
69
70
  var _a;
70
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
71
+ const provider = yield ((_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect());
72
+ if (provider) {
73
+ return provider;
74
+ }
75
+ // On mobile web (outside the wallet's in-app browser) there is no injected
76
+ // provider for these wallets, so signing silently returns nothing. Redirect
77
+ // into the wallet's in-app browser so signing can continue there, or throw a
78
+ // clear error when neither a provider nor a redirect is possible.
79
+ if (utils.isMobile() && !this.isInstalledOnBrowser()) {
80
+ const didOpenInAppBrowser = this.openInAppBrowserIfRequired();
81
+ if (!didOpenInAppBrowser) {
82
+ throw new utils.WalletRequiresInAppBrowserError(this.name);
83
+ }
84
+ }
85
+ return undefined;
71
86
  });
72
87
  }
73
88
  createUiTransaction(from) {
@@ -118,12 +133,21 @@ class InjectedWalletBase extends solanaCore.SolanaWalletConnector {
118
133
  }
119
134
  signMessage(messageToSign) {
120
135
  return _tslib.__awaiter(this, void 0, void 0, function* () {
121
- var _a, _b;
122
- const walletAddress = yield ((_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.getAddress());
123
- if (walletAddress && this.isLedgerAddress(walletAddress)) {
136
+ var _a;
137
+ // Go through getAddress (not the helper directly) so that on mobile web an
138
+ // in-app-browser wallet redirects into its in-app browser instead of
139
+ // silently signing nothing.
140
+ const walletAddress = yield this.getAddress();
141
+ // No address means there is no provider to sign with (e.g. getAddress
142
+ // redirected into the wallet's in-app browser on mobile), so stop here
143
+ // instead of attempting a providerless sign.
144
+ if (!walletAddress) {
145
+ return undefined;
146
+ }
147
+ if (this.isLedgerAddress(walletAddress)) {
124
148
  throw new SignMessageNotSupportedError.SignMessageNotSupportedError(this.name);
125
149
  }
126
- return (_b = this.solProviderHelper) === null || _b === void 0 ? void 0 : _b.signMessage(messageToSign);
150
+ return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.signMessage(messageToSign);
127
151
  });
128
152
  }
129
153
  getConnectedAccounts() {
@@ -2,6 +2,7 @@
2
2
  import { __awaiter } from '../../../_virtual/_tslib.js';
3
3
  import { PublicKey } from '@solana/web3.js';
4
4
  import { SolanaWalletConnector, SolanaUiTransaction } from '@dynamic-labs/solana-core';
5
+ import { isMobile, WalletRequiresInAppBrowserError } from '@dynamic-labs/utils';
5
6
  import { getWalletMetadataFromWalletBook } from '@dynamic-labs/wallet-connector-core';
6
7
  import { SolProviderHelper } from '../../SolProviderHelper/SolProviderHelper.js';
7
8
  import { SignMessageNotSupportedError } from '../../errors/SignMessageNotSupportedError.js';
@@ -63,7 +64,21 @@ class InjectedWalletBase extends SolanaWalletConnector {
63
64
  getSigner() {
64
65
  return __awaiter(this, void 0, void 0, function* () {
65
66
  var _a;
66
- return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect();
67
+ const provider = yield ((_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.connect());
68
+ if (provider) {
69
+ return provider;
70
+ }
71
+ // On mobile web (outside the wallet's in-app browser) there is no injected
72
+ // provider for these wallets, so signing silently returns nothing. Redirect
73
+ // into the wallet's in-app browser so signing can continue there, or throw a
74
+ // clear error when neither a provider nor a redirect is possible.
75
+ if (isMobile() && !this.isInstalledOnBrowser()) {
76
+ const didOpenInAppBrowser = this.openInAppBrowserIfRequired();
77
+ if (!didOpenInAppBrowser) {
78
+ throw new WalletRequiresInAppBrowserError(this.name);
79
+ }
80
+ }
81
+ return undefined;
67
82
  });
68
83
  }
69
84
  createUiTransaction(from) {
@@ -114,12 +129,21 @@ class InjectedWalletBase extends SolanaWalletConnector {
114
129
  }
115
130
  signMessage(messageToSign) {
116
131
  return __awaiter(this, void 0, void 0, function* () {
117
- var _a, _b;
118
- const walletAddress = yield ((_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.getAddress());
119
- if (walletAddress && this.isLedgerAddress(walletAddress)) {
132
+ var _a;
133
+ // Go through getAddress (not the helper directly) so that on mobile web an
134
+ // in-app-browser wallet redirects into its in-app browser instead of
135
+ // silently signing nothing.
136
+ const walletAddress = yield this.getAddress();
137
+ // No address means there is no provider to sign with (e.g. getAddress
138
+ // redirected into the wallet's in-app browser on mobile), so stop here
139
+ // instead of attempting a providerless sign.
140
+ if (!walletAddress) {
141
+ return undefined;
142
+ }
143
+ if (this.isLedgerAddress(walletAddress)) {
120
144
  throw new SignMessageNotSupportedError(this.name);
121
145
  }
122
- return (_b = this.solProviderHelper) === null || _b === void 0 ? void 0 : _b.signMessage(messageToSign);
146
+ return (_a = this.solProviderHelper) === null || _a === void 0 ? void 0 : _a.signMessage(messageToSign);
123
147
  });
124
148
  }
125
149
  getConnectedAccounts() {
@@ -3,7 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var _tslib = require('../../../_virtual/_tslib.cjs');
7
6
  var utils = require('@dynamic-labs/utils');
8
7
  var InjectedWalletBase = require('../InjectedWalletBase/InjectedWalletBase.cjs');
9
8
 
@@ -13,22 +12,15 @@ class PhantomInjected extends InjectedWalletBase.InjectedWalletBase {
13
12
  this.name = 'Phantom';
14
13
  this.overrideKey = 'phantom';
15
14
  }
16
- getAddress() {
17
- const _super = Object.create(null, {
18
- getAddress: { get: () => super.getAddress }
19
- });
20
- return _tslib.__awaiter(this, void 0, void 0, function* () {
21
- if (this.isInstalledOnBrowser()) {
22
- return _super.getAddress.call(this);
23
- }
24
- if (utils.isMobile()) {
25
- utils.handleMobileWalletRedirect({
26
- nativeLink: 'phantom://browse',
27
- universalLink: 'https://phantom.app/ul/browse',
28
- });
29
- }
30
- return undefined;
31
- });
15
+ openInAppBrowserIfRequired() {
16
+ if (utils.isMobile() && !this.isInstalledOnBrowser()) {
17
+ utils.handleMobileWalletRedirect({
18
+ nativeLink: 'phantom://browse',
19
+ universalLink: 'https://phantom.app/ul/browse',
20
+ });
21
+ return true;
22
+ }
23
+ return false;
32
24
  }
33
25
  canGetChainAddress() {
34
26
  var _a, _b;
@@ -2,6 +2,6 @@ import { InjectedWalletBase } from '../InjectedWalletBase';
2
2
  export declare class PhantomInjected extends InjectedWalletBase {
3
3
  name: string;
4
4
  overrideKey: string;
5
- getAddress(): Promise<string | undefined>;
5
+ openInAppBrowserIfRequired(): boolean;
6
6
  canGetChainAddress(): boolean;
7
7
  }
@@ -1,5 +1,4 @@
1
1
  'use client'
2
- import { __awaiter } from '../../../_virtual/_tslib.js';
3
2
  import { isMobile, handleMobileWalletRedirect } from '@dynamic-labs/utils';
4
3
  import { InjectedWalletBase } from '../InjectedWalletBase/InjectedWalletBase.js';
5
4
 
@@ -9,22 +8,15 @@ class PhantomInjected extends InjectedWalletBase {
9
8
  this.name = 'Phantom';
10
9
  this.overrideKey = 'phantom';
11
10
  }
12
- getAddress() {
13
- const _super = Object.create(null, {
14
- getAddress: { get: () => super.getAddress }
15
- });
16
- return __awaiter(this, void 0, void 0, function* () {
17
- if (this.isInstalledOnBrowser()) {
18
- return _super.getAddress.call(this);
19
- }
20
- if (isMobile()) {
21
- handleMobileWalletRedirect({
22
- nativeLink: 'phantom://browse',
23
- universalLink: 'https://phantom.app/ul/browse',
24
- });
25
- }
26
- return undefined;
27
- });
11
+ openInAppBrowserIfRequired() {
12
+ if (isMobile() && !this.isInstalledOnBrowser()) {
13
+ handleMobileWalletRedirect({
14
+ nativeLink: 'phantom://browse',
15
+ universalLink: 'https://phantom.app/ul/browse',
16
+ });
17
+ return true;
18
+ }
19
+ return false;
28
20
  }
29
21
  canGetChainAddress() {
30
22
  var _a, _b;