@bounded-sh/client 0.0.17 → 0.0.18

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 (37) hide show
  1. package/README.md +2 -1
  2. package/dist/auth/index.d.ts +2 -4
  3. package/dist/auth/providers/phantom-wallet-provider.d.ts +3 -2
  4. package/dist/auth/providers/privy-wallet-provider.d.ts +10 -7
  5. package/dist/auth/providers/solana-mobile-wallet-provider.d.ts +3 -2
  6. package/dist/auth/solana-rpc.d.ts +8 -0
  7. package/dist/index.js +246 -188
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +246 -188
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/{index.native-DlMO7aHv.mjs → index.native-DahSrHrM.mjs} +138 -62
  12. package/dist/index.native-DahSrHrM.mjs.map +1 -0
  13. package/dist/{index.native-DoiNBZlU.js → index.native-Dr3FOz16.js} +141 -64
  14. package/dist/index.native-Dr3FOz16.js.map +1 -0
  15. package/dist/index.native.js +1 -1
  16. package/dist/index.native.mjs +1 -1
  17. package/dist/{phantom-wallet-provider-DUdnFoyb.js → phantom-wallet-provider-CeLJEdcL.js} +7 -18
  18. package/dist/phantom-wallet-provider-CeLJEdcL.js.map +1 -0
  19. package/dist/{phantom-wallet-provider-DWG1LVJf.mjs → phantom-wallet-provider-l-CNnHPs.mjs} +7 -18
  20. package/dist/phantom-wallet-provider-l-CNnHPs.mjs.map +1 -0
  21. package/dist/{privy-wallet-provider-Kv6H3xcS.js → privy-wallet-provider-BSwx78fY.js} +69 -90
  22. package/dist/privy-wallet-provider-BSwx78fY.js.map +1 -0
  23. package/dist/{privy-wallet-provider-CyNLekvY.mjs → privy-wallet-provider-BWM8TNO9.mjs} +68 -89
  24. package/dist/privy-wallet-provider-BWM8TNO9.mjs.map +1 -0
  25. package/dist/{solana-mobile-wallet-provider-BfHBucO0.js → solana-mobile-wallet-provider-BvCrAgk8.js} +39 -25
  26. package/dist/solana-mobile-wallet-provider-BvCrAgk8.js.map +1 -0
  27. package/dist/{solana-mobile-wallet-provider-CKOSbLRd.mjs → solana-mobile-wallet-provider-C78VWmM-.mjs} +39 -25
  28. package/dist/solana-mobile-wallet-provider-C78VWmM-.mjs.map +1 -0
  29. package/package.json +2 -2
  30. package/dist/index.native-DlMO7aHv.mjs.map +0 -1
  31. package/dist/index.native-DoiNBZlU.js.map +0 -1
  32. package/dist/phantom-wallet-provider-DUdnFoyb.js.map +0 -1
  33. package/dist/phantom-wallet-provider-DWG1LVJf.mjs.map +0 -1
  34. package/dist/privy-wallet-provider-CyNLekvY.mjs.map +0 -1
  35. package/dist/privy-wallet-provider-Kv6H3xcS.js.map +0 -1
  36. package/dist/solana-mobile-wallet-provider-BfHBucO0.js.map +0 -1
  37. package/dist/solana-mobile-wallet-provider-CKOSbLRd.mjs.map +0 -1
package/dist/index.js CHANGED
@@ -6694,6 +6694,50 @@ const MODAL_CSS = `
6694
6694
  #bounded-auth-modal .hidden{display:none;}
6695
6695
  @media (max-width:480px){#bounded-auth-modal .ba-card{max-width:none;border-radius:16px;}}`;
6696
6696
 
6697
+ const SURFNET_RPC_URL = "https://surfpool.fly.dev";
6698
+ const SUPPORTED_SOLANA_NETWORKS = new Set([
6699
+ "solana_devnet",
6700
+ "solana_mainnet",
6701
+ "surfnet",
6702
+ ]);
6703
+ function normalizeSolanaRpcUrl(rpcUrl) {
6704
+ if (typeof rpcUrl !== "string")
6705
+ return null;
6706
+ const trimmed = rpcUrl.trim();
6707
+ return trimmed.length > 0 ? trimmed : null;
6708
+ }
6709
+ function isSupportedSolanaRpcNetwork(network) {
6710
+ return typeof network === "string" && SUPPORTED_SOLANA_NETWORKS.has(network);
6711
+ }
6712
+ function resolveSolanaWalletStandardChain(network, context) {
6713
+ switch (network) {
6714
+ case "solana_devnet":
6715
+ return "solana:devnet";
6716
+ case "solana_mainnet":
6717
+ return "solana:mainnet";
6718
+ case "surfnet":
6719
+ return "solana:localnet";
6720
+ case undefined:
6721
+ case null:
6722
+ case "":
6723
+ throw new Error(`${context} requires an explicit Solana network. ` +
6724
+ `Provide one of: solana_devnet, solana_mainnet, surfnet.`);
6725
+ default:
6726
+ throw new Error(`${context} does not support Solana network "${network}". ` +
6727
+ `Expected one of: solana_devnet, solana_mainnet, surfnet.`);
6728
+ }
6729
+ }
6730
+ function resolveSolanaRpcUrl(explicitRpcUrl, network, context) {
6731
+ if (network != null && network !== "" && !isSupportedSolanaRpcNetwork(network)) {
6732
+ throw new Error(`${context} does not support Solana network "${network}". ` +
6733
+ `Expected one of: solana_devnet, solana_mainnet, surfnet.`);
6734
+ }
6735
+ const rpcUrl = normalizeSolanaRpcUrl(explicitRpcUrl);
6736
+ if (rpcUrl)
6737
+ return rpcUrl;
6738
+ throw new Error(`${context} requires an explicit Solana RPC URL. Pass config.rpcUrl before signing or submitting onchain transactions.`);
6739
+ }
6740
+
6697
6741
  const PKCE_STORE_KEY = 'bounded.oidc.pkce';
6698
6742
  // Active session store (Web on web, RN on React Native) — selected by config,
6699
6743
  // not by `typeof window` (truthy on RN). OIDC redirect/popup is web-only, but the
@@ -7000,7 +7044,7 @@ async function exchangeCode(code, verifier, redirectUri) {
7000
7044
  let currentAuthProvider = null;
7001
7045
  let currentAuthMethod = null;
7002
7046
  let initConfig = null;
7003
- // --- localStorage helpers: track which auth method the user last logged in with ---
7047
+ // --- localStorage helpers: track which auth method created the active session ---
7004
7048
  const STORED_AUTH_METHOD_KEY$1 = 'bounded_last_auth_method';
7005
7049
  function getStoredAuthMethod() {
7006
7050
  try {
@@ -7024,7 +7068,7 @@ function setStoredAuthMethod(method) {
7024
7068
  }
7025
7069
  }
7026
7070
  /**
7027
- * Clears the session if it was created before auth method tracking (legacy session).
7071
+ * Clears the session if it was created by a different auth method.
7028
7072
  * Returns true if the session was cleared, false if the session is compatible.
7029
7073
  *
7030
7074
  * Dispatches to the correct session manager based on the current auth method
@@ -7032,18 +7076,17 @@ function setStoredAuthMethod(method) {
7032
7076
  * are properly cleared.
7033
7077
  */
7034
7078
  function clearIncompatibleSession() {
7035
- if (getStoredAuthMethod() !== null) {
7036
- return false; // Auth method is tracked — session is compatible
7079
+ if (getStoredAuthMethod() === currentAuthMethod) {
7080
+ return false;
7037
7081
  }
7038
- // Legacy session (no stored auth method) — clear it so the user re-authenticates
7039
- // with the correct provider.
7040
- // Clear both managers — on web the RN manager is a no-op (not configured),
7041
- // on RN the web manager is a no-op (no localStorage).
7082
+ // Clear both managers: on web the RN manager is a no-op (not configured),
7083
+ // and on RN the web manager is a no-op (no localStorage).
7042
7084
  core.WebSessionManager.clearSession();
7043
7085
  try {
7044
7086
  core.ReactNativeSessionManager.clearSession();
7045
7087
  }
7046
7088
  catch ( /* not configured on web */_a) { /* not configured on web */ }
7089
+ setStoredAuthMethod(null);
7047
7090
  return true;
7048
7091
  }
7049
7092
  // Lazy loaders for web-only providers.
@@ -7062,17 +7105,67 @@ async function loadSolanaMobileWalletProvider() {
7062
7105
  const mod = await Promise.resolve().then(function () { return solanaMobileWalletProvider; });
7063
7106
  return mod.SolanaMobileWalletProvider;
7064
7107
  }
7108
+ function requireWebPrivyConfig(config) {
7109
+ if (!config.privyConfig || typeof config.privyConfig.appId !== 'string' || config.privyConfig.appId.trim() === '') {
7110
+ throw new Error('Privy auth requires config.privyConfig.appId; no default Privy app is used.');
7111
+ }
7112
+ if (!config.privyConfig.config || typeof config.privyConfig.config !== 'object') {
7113
+ throw new Error('Privy auth requires config.privyConfig.config for the app-scoped Privy provider.');
7114
+ }
7115
+ return config.privyConfig;
7116
+ }
7117
+ function getConfiguredSolanaNetwork(config) {
7118
+ if (typeof config.chain !== 'string')
7119
+ return null;
7120
+ const chain = config.chain.trim();
7121
+ if (chain === '' || chain === 'offchain')
7122
+ return null;
7123
+ return chain;
7124
+ }
7125
+ function mobileWalletClusterFromNetwork(network) {
7126
+ switch (network) {
7127
+ case "solana_devnet":
7128
+ return "devnet";
7129
+ case "solana_mainnet":
7130
+ return "mainnet-beta";
7131
+ case "surfnet":
7132
+ return "localnet";
7133
+ case null:
7134
+ return null;
7135
+ default:
7136
+ resolveSolanaWalletStandardChain(network, "Mobile wallet auth");
7137
+ return null;
7138
+ }
7139
+ }
7140
+ function requireMobileWalletConfig(config) {
7141
+ var _a, _b, _c;
7142
+ const configuredNetwork = getConfiguredSolanaNetwork(config);
7143
+ const cluster = (_b = (_a = config.mobileWalletConfig) === null || _a === void 0 ? void 0 : _a.cluster) !== null && _b !== void 0 ? _b : mobileWalletClusterFromNetwork(configuredNetwork);
7144
+ if (!cluster) {
7145
+ throw new Error("Mobile wallet auth requires an explicit Solana network. " +
7146
+ "Pass config.chain as solana_devnet, solana_mainnet, or surfnet, " +
7147
+ "or pass mobileWalletConfig.cluster.");
7148
+ }
7149
+ return Object.assign(Object.assign({}, ((_c = config.mobileWalletConfig) !== null && _c !== void 0 ? _c : {})), { cluster });
7150
+ }
7065
7151
  async function hotSwapToMWAProvider(config) {
7066
- var _a, _b;
7067
- const rpcUrl = (_a = config.rpcUrl) !== null && _a !== void 0 ? _a : null;
7152
+ var _a;
7153
+ const rpcUrl = normalizeSolanaRpcUrl(config.rpcUrl);
7154
+ const configuredNetwork = getConfiguredSolanaNetwork(config);
7068
7155
  const SolanaMobileWalletProvider = await loadSolanaMobileWalletProvider();
7069
- const mwaConfig = (_b = config.mobileWalletConfig) !== null && _b !== void 0 ? _b : {
7070
- appIdentity: {
7071
- name: config.name || undefined,
7072
- uri: getPlatform().getLocationOrigin(),
7073
- },
7074
- };
7075
- const mwaProvider = new SolanaMobileWalletProvider(rpcUrl, mwaConfig);
7156
+ const mwaConfig = config.mobileWalletConfig
7157
+ ? requireMobileWalletConfig(config)
7158
+ : {
7159
+ appIdentity: {
7160
+ name: config.name || undefined,
7161
+ uri: getPlatform().getLocationOrigin(),
7162
+ },
7163
+ cluster: (_a = mobileWalletClusterFromNetwork(configuredNetwork)) !== null && _a !== void 0 ? _a : undefined,
7164
+ };
7165
+ if (!mwaConfig.cluster) {
7166
+ throw new Error("Mobile wallet auth requires config.chain or mobileWalletConfig.cluster before switching providers.");
7167
+ }
7168
+ const mwaProvider = new SolanaMobileWalletProvider(rpcUrl, mwaConfig, configuredNetwork);
7076
7169
  let provider = mwaProvider;
7077
7170
  if (config.chain === "offchain") {
7078
7171
  provider = new OffchainAuthProvider(mwaProvider);
@@ -7087,11 +7180,8 @@ async function hotSwapToMWAProvider(config) {
7087
7180
  setAuthProviderInstance(provider);
7088
7181
  return provider;
7089
7182
  }
7090
- const SOLANA_DEVNET_RPC_URL = "https://idelle-8nxsep-fast-devnet.helius-rpc.com";
7091
- const SOLANA_MAINNET_RPC_URL = "https://celestia-cegncv-fast-mainnet.helius-rpc.com";
7092
- const SURFNET_RPC_URL$2 = "https://surfpool.fly.dev";
7093
7183
  async function getAuthProvider(config) {
7094
- var _a, _b, _c;
7184
+ var _a, _b;
7095
7185
  if (currentAuthProvider) {
7096
7186
  return currentAuthProvider;
7097
7187
  }
@@ -7105,17 +7195,12 @@ async function getAuthProvider(config) {
7105
7195
  currentAuthProvider = new MockAuthProvider();
7106
7196
  return currentAuthProvider;
7107
7197
  }
7108
- // If the user previously logged in with a specific method, use that instead
7109
- const validAuthMethods = ['email', 'phantom', 'wallet', 'rainbowkit', 'coinbase-smart-wallet', 'onboard', 'mobile-wallet-adapter', 'guest', 'privy', 'privy-expo', 'none'];
7110
- const storedMethod = getStoredAuthMethod();
7111
- const authMethod = (storedMethod && validAuthMethods.includes(storedMethod))
7112
- ? storedMethod
7113
- : (config.authMethod || "email");
7114
- if (storedMethod && !validAuthMethods.includes(storedMethod)) {
7115
- // Invalid stored value — clear it
7116
- setStoredAuthMethod(null);
7117
- }
7118
- const rpcUrl = (_a = config.rpcUrl) !== null && _a !== void 0 ? _a : null;
7198
+ const authMethod = config.authMethod;
7199
+ if (!authMethod) {
7200
+ throw new Error("authMethod is required to initialize auth provider; configure the single intended auth method explicitly.");
7201
+ }
7202
+ const rpcUrl = normalizeSolanaRpcUrl(config.rpcUrl);
7203
+ const configuredNetwork = getConfiguredSolanaNetwork(config);
7119
7204
  currentAuthMethod = authMethod;
7120
7205
  // Clear, actionable error when the BROWSER build (`bounded-sh`) is loaded in a
7121
7206
  // non-browser (Node) runtime. The wallet providers below need `window`; without
@@ -7145,7 +7230,7 @@ async function getAuthProvider(config) {
7145
7230
  break;
7146
7231
  case "phantom": {
7147
7232
  const { PhantomWalletProvider } = await loadPhantomWalletProvider();
7148
- currentAuthProvider = new PhantomWalletProvider(rpcUrl, config.phantomConfig);
7233
+ currentAuthProvider = new PhantomWalletProvider(rpcUrl, config.phantomConfig, configuredNetwork);
7149
7234
  // MWA hot-swap is always available (custom modal shows MWA button on Android)
7150
7235
  currentAuthProvider.onSwitchToMWA =
7151
7236
  () => hotSwapToMWAProvider(config);
@@ -7155,8 +7240,9 @@ async function getAuthProvider(config) {
7155
7240
  // Web Privy: a co-equal login route alongside email/phantom/guest. The
7156
7241
  // Privy embedded/external Solana wallet signs the SIWS challenge, so the
7157
7242
  // session is minted through the same wallet path as Phantom.
7243
+ const privyConfig = requireWebPrivyConfig(config);
7158
7244
  const PrivyWalletProvider = await loadPrivyWalletProvider();
7159
- currentAuthProvider = new PrivyWalletProvider((_b = config.name) !== null && _b !== void 0 ? _b : null, (_c = config.logoUrl) !== null && _c !== void 0 ? _c : null, config.privyConfig, rpcUrl);
7245
+ currentAuthProvider = new PrivyWalletProvider((_a = config.name) !== null && _a !== void 0 ? _a : null, (_b = config.logoUrl) !== null && _b !== void 0 ? _b : null, privyConfig, rpcUrl, configuredNetwork);
7160
7246
  break;
7161
7247
  }
7162
7248
  case "privy-expo":
@@ -7171,7 +7257,7 @@ async function getAuthProvider(config) {
7171
7257
  break;
7172
7258
  case "mobile-wallet-adapter": {
7173
7259
  const SolanaMobileWalletProvider = await loadSolanaMobileWalletProvider();
7174
- currentAuthProvider = new SolanaMobileWalletProvider(rpcUrl, config.mobileWalletConfig);
7260
+ currentAuthProvider = new SolanaMobileWalletProvider(rpcUrl, requireMobileWalletConfig(config), configuredNetwork);
7175
7261
  break;
7176
7262
  }
7177
7263
  case "onboard":
@@ -7241,13 +7327,14 @@ async function signInAnonymously() {
7241
7327
  * (web localStorage / RN storage) and identity model. `init()` must have run first.
7242
7328
  */
7243
7329
  async function loginWithPrivy(options) {
7244
- var _a, _b, _c;
7330
+ var _a, _b;
7245
7331
  assertBrowserAuthEnv('loginWithPrivy');
7246
7332
  const coreConfig = await core.getConfig();
7247
7333
  let provider;
7248
7334
  if (getPlatform().hasDOM) {
7335
+ const privyConfig = requireWebPrivyConfig(coreConfig);
7249
7336
  const PrivyWalletProvider = await loadPrivyWalletProvider();
7250
- provider = new PrivyWalletProvider((_a = coreConfig.name) !== null && _a !== void 0 ? _a : null, (_b = coreConfig.logoUrl) !== null && _b !== void 0 ? _b : null, coreConfig.privyConfig, (_c = coreConfig.rpcUrl) !== null && _c !== void 0 ? _c : null);
7337
+ provider = new PrivyWalletProvider((_a = coreConfig.name) !== null && _a !== void 0 ? _a : null, (_b = coreConfig.logoUrl) !== null && _b !== void 0 ? _b : null, privyConfig, normalizeSolanaRpcUrl(coreConfig.rpcUrl), getConfiguredSolanaNetwork(coreConfig));
7251
7338
  currentAuthMethod = 'privy';
7252
7339
  }
7253
7340
  else {
@@ -7393,15 +7480,13 @@ async function logout$1() {
7393
7480
  throw new Error("Auth provider not initialized. Please call init() first.");
7394
7481
  }
7395
7482
  // Revoke the refresh-token family server-side BEFORE the provider clears the
7396
- // local session (so we still have the token + issuer to revoke). Best-effort:
7397
- // revokeSession swallows errors so logout never hangs/fails on a network blip.
7398
- try {
7399
- const sm = core.getActiveSessionManager();
7400
- const refreshToken = sm.getRefreshToken();
7401
- if (refreshToken)
7402
- await core.revokeSession(refreshToken, (_a = sm.getIssuer()) !== null && _a !== void 0 ? _a : undefined);
7403
- }
7404
- catch ( /* proceed with local logout regardless */_b) { /* proceed with local logout regardless */ }
7483
+ // local session (so we still have the token + issuer to revoke). If revoke
7484
+ // fails, surface the error and leave local state intact so callers do not
7485
+ // mistake a local-only logout for server revocation.
7486
+ const sm = core.getActiveSessionManager();
7487
+ const refreshToken = sm.getRefreshToken();
7488
+ if (refreshToken)
7489
+ await core.revokeSession(refreshToken, (_a = sm.getIssuer()) !== null && _a !== void 0 ? _a : undefined);
7405
7490
  await currentAuthProvider.logout();
7406
7491
  setStoredAuthMethod(null);
7407
7492
  currentAuthProvider = null;
@@ -7856,7 +7941,7 @@ class PhantomWalletProvider {
7856
7941
  setLoginOverrides(opts) {
7857
7942
  this.loginOverrides = opts;
7858
7943
  }
7859
- constructor(networkUrl = null, config = {}) {
7944
+ constructor(networkUrl = null, config = {}, configuredNetwork = null) {
7860
7945
  this.containerElement = null;
7861
7946
  this.root = null;
7862
7947
  this.phantomMethods = null;
@@ -7869,6 +7954,7 @@ class PhantomWalletProvider {
7869
7954
  /** Callback to swap to a Mobile Wallet Adapter provider when the user clicks "Connect Mobile Wallet" */
7870
7955
  this.onSwitchToMWA = null;
7871
7956
  this.networkUrl = networkUrl;
7957
+ this.configuredNetwork = configuredNetwork;
7872
7958
  this.config = config;
7873
7959
  if (typeof window === 'undefined') {
7874
7960
  throw new Error('PhantomWalletProvider can only be instantiated in a browser environment');
@@ -7895,9 +7981,9 @@ class PhantomWalletProvider {
7895
7981
  hasSocialProviders() {
7896
7982
  return this.resolvedProviders.some(p => p !== 'injected');
7897
7983
  }
7898
- static getInstance(networkUrl, config) {
7984
+ static getInstance(networkUrl, config, configuredNetwork = null) {
7899
7985
  if (!PhantomWalletProvider.instance) {
7900
- new PhantomWalletProvider(networkUrl, config);
7986
+ new PhantomWalletProvider(networkUrl, config, configuredNetwork);
7901
7987
  }
7902
7988
  return PhantomWalletProvider.instance;
7903
7989
  }
@@ -8799,7 +8885,7 @@ class PhantomWalletProvider {
8799
8885
  }
8800
8886
  const rpcUrl = this.getRpcUrl(solTransactionData.network);
8801
8887
  const connection = new web3_js.Connection(rpcUrl, 'confirmed');
8802
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
8888
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
8803
8889
  try {
8804
8890
  const remainingAccounts = core.convertRemainingAccounts(solTransactionData.txArgs[0].remainingAccounts);
8805
8891
  const app_id = solTransactionData.appId;
@@ -9021,7 +9107,7 @@ class PhantomWalletProvider {
9021
9107
  }
9022
9108
  const rpcUrl = this.getRpcUrl();
9023
9109
  const connection = new web3_js.Connection(rpcUrl, 'confirmed');
9024
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
9110
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
9025
9111
  try {
9026
9112
  // Get fresh blockhash and set it on the transaction before signing
9027
9113
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
@@ -9154,19 +9240,7 @@ class PhantomWalletProvider {
9154
9240
  * Private Helpers
9155
9241
  * ----------------------------------------------------------- */
9156
9242
  getRpcUrl(network) {
9157
- if (this.networkUrl) {
9158
- return this.networkUrl;
9159
- }
9160
- if (network === 'solana_devnet') {
9161
- return SOLANA_DEVNET_RPC_URL;
9162
- }
9163
- else if (network === 'solana_mainnet') {
9164
- return SOLANA_MAINNET_RPC_URL;
9165
- }
9166
- else if (network === 'surfnet') {
9167
- return SURFNET_RPC_URL$2;
9168
- }
9169
- return SOLANA_MAINNET_RPC_URL; // default to mainnet
9243
+ return resolveSolanaRpcUrl(this.networkUrl, network !== null && network !== void 0 ? network : this.configuredNetwork, "Phantom wallet Solana transaction");
9170
9244
  }
9171
9245
  async signAndSendViaPhantom(transaction) {
9172
9246
  var _a, _b, _c;
@@ -9613,8 +9687,10 @@ async function signWithFreshActivation(theme, signFn, noResultError = 'MWA retur
9613
9687
  * normalized to `solana:mainnet`.
9614
9688
  */
9615
9689
  function mapChainToWalletStandard(input) {
9616
- if (!input)
9617
- return 'solana:mainnet';
9690
+ if (!input) {
9691
+ throw new Error("Solana mobile wallet auth requires an explicit cluster. " +
9692
+ "Pass mobileWalletConfig.cluster or config.chain.");
9693
+ }
9618
9694
  let s = String(input).toLowerCase();
9619
9695
  while (s.startsWith('solana:'))
9620
9696
  s = s.slice('solana:'.length);
@@ -9626,7 +9702,22 @@ function mapChainToWalletStandard(input) {
9626
9702
  return 'solana:testnet';
9627
9703
  if (s === 'localnet')
9628
9704
  return 'solana:localnet';
9629
- return 'solana:mainnet';
9705
+ throw new Error(`Solana mobile wallet auth does not support cluster "${input}". ` +
9706
+ "Expected mainnet-beta, devnet, testnet, or localnet.");
9707
+ }
9708
+ function mapClusterToRpcNetwork(input) {
9709
+ if (!input)
9710
+ return null;
9711
+ let s = String(input).toLowerCase();
9712
+ while (s.startsWith('solana:'))
9713
+ s = s.slice('solana:'.length);
9714
+ if (s === 'mainnet-beta' || s === 'mainnet')
9715
+ return 'solana_mainnet';
9716
+ if (s === 'devnet')
9717
+ return 'solana_devnet';
9718
+ if (s === 'localnet')
9719
+ return 'surfnet';
9720
+ return null;
9630
9721
  }
9631
9722
  /**
9632
9723
  * Serialize a Transaction/VersionedTransaction to a Uint8Array wire payload
@@ -9802,7 +9893,8 @@ async function registerMobileWalletAdapter(config) {
9802
9893
  * acceptable given the alternative was broken on Seeker.
9803
9894
  */
9804
9895
  class SolanaMobileWalletProvider {
9805
- constructor(networkUrl = null, config = {}) {
9896
+ constructor(networkUrl = null, config = {}, configuredNetwork = null) {
9897
+ var _a;
9806
9898
  /** LocalSolanaMobileWalletAdapterWallet, lazy-constructed in ensureWallet(). */
9807
9899
  this.wallet = null;
9808
9900
  /**
@@ -9816,6 +9908,7 @@ class SolanaMobileWalletProvider {
9816
9908
  /** Cached public key string for the connected MWA wallet (native). */
9817
9909
  this.nativeAddress = null;
9818
9910
  this.networkUrl = networkUrl;
9911
+ this.configuredNetwork = configuredNetwork;
9819
9912
  this.config = config;
9820
9913
  // Allow construction in true React Native environments: getPlatform().hasDOM
9821
9914
  // is false there even though `typeof window === 'object'` (RN exposes a
@@ -9844,7 +9937,7 @@ class SolanaMobileWalletProvider {
9844
9937
  name: 'Bounded App',
9845
9938
  uri: fallbackUri,
9846
9939
  };
9847
- this.cluster = config.cluster || 'mainnet-beta';
9940
+ this.cluster = (_a = config.cluster) !== null && _a !== void 0 ? _a : '';
9848
9941
  // Hydrate cached MWA auth_token from storage on native so we can
9849
9942
  // skip the wallet-pick popup after a cold-start when the underlying
9850
9943
  // wallet authorization is still valid. Sync storage call per the
@@ -9861,15 +9954,15 @@ class SolanaMobileWalletProvider {
9861
9954
  }
9862
9955
  }
9863
9956
  }
9864
- catch (_a) {
9957
+ catch (_b) {
9865
9958
  // Corrupt or unreadable cache — ignore. login() will re-auth.
9866
9959
  }
9867
9960
  }
9868
9961
  SolanaMobileWalletProvider.instance = this;
9869
9962
  }
9870
- static getInstance(networkUrl, config) {
9963
+ static getInstance(networkUrl, config, configuredNetwork = null) {
9871
9964
  if (!SolanaMobileWalletProvider.instance) {
9872
- new SolanaMobileWalletProvider(networkUrl, config);
9965
+ new SolanaMobileWalletProvider(networkUrl, config, configuredNetwork);
9873
9966
  }
9874
9967
  return SolanaMobileWalletProvider.instance;
9875
9968
  }
@@ -9924,7 +10017,13 @@ class SolanaMobileWalletProvider {
9924
10017
  return wallet.accounts[0];
9925
10018
  }
9926
10019
  /** Returns the active wallet-standard chain identifier (e.g. 'solana:mainnet'). */
9927
- getChain() {
10020
+ getChain(network) {
10021
+ if (network) {
10022
+ return resolveSolanaWalletStandardChain(network, "Solana mobile wallet transaction");
10023
+ }
10024
+ if (this.configuredNetwork) {
10025
+ return resolveSolanaWalletStandardChain(this.configuredNetwork, "Solana mobile wallet transaction");
10026
+ }
9928
10027
  return mapChainToWalletStandard(this.cluster);
9929
10028
  }
9930
10029
  /**
@@ -10386,7 +10485,7 @@ class SolanaMobileWalletProvider {
10386
10485
  const connectedPubkey = new web3_js.PublicKey(this.nativeAddress);
10387
10486
  const rpcUrl = this.getRpcUrl();
10388
10487
  const connection = new web3_js.Connection(rpcUrl, 'confirmed');
10389
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
10488
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
10390
10489
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
10391
10490
  const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
10392
10491
  if (isLegacyTransaction) {
@@ -10444,7 +10543,7 @@ class SolanaMobileWalletProvider {
10444
10543
  const chain = this.getChain();
10445
10544
  const rpcUrl = this.getRpcUrl();
10446
10545
  const connection = new web3_js.Connection(rpcUrl, 'confirmed');
10447
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
10546
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
10448
10547
  try {
10449
10548
  // Preserve existing prep: refresh blockhash and set fee payer.
10450
10549
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
@@ -10524,10 +10623,10 @@ class SolanaMobileWalletProvider {
10524
10623
  const account = await this.ensureAuthorized();
10525
10624
  const connectedPubkey = new web3_js.PublicKey(account.publicKey);
10526
10625
  const wallet = await this.ensureWallet();
10527
- const chain = this.getChain();
10626
+ const chain = this.getChain(solTransactionData.network);
10528
10627
  const rpcUrl = this.getRpcUrl(solTransactionData.network);
10529
10628
  const connection = new web3_js.Connection(rpcUrl, 'confirmed');
10530
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
10629
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
10531
10630
  try {
10532
10631
  const remainingAccounts = core.convertRemainingAccounts(solTransactionData.txArgs[0].remainingAccounts);
10533
10632
  const app_id = solTransactionData.appId;
@@ -10703,19 +10802,8 @@ class SolanaMobileWalletProvider {
10703
10802
  * Private Helpers
10704
10803
  * ----------------------------------------------------------- */
10705
10804
  getRpcUrl(network) {
10706
- if (this.networkUrl) {
10707
- return this.networkUrl;
10708
- }
10709
- if (network === 'solana_devnet') {
10710
- return SOLANA_DEVNET_RPC_URL;
10711
- }
10712
- else if (network === 'solana_mainnet') {
10713
- return SOLANA_MAINNET_RPC_URL;
10714
- }
10715
- else if (network === 'surfnet') {
10716
- return SURFNET_RPC_URL$2;
10717
- }
10718
- return SOLANA_MAINNET_RPC_URL;
10805
+ var _a;
10806
+ return resolveSolanaRpcUrl(this.networkUrl, (_a = network !== null && network !== void 0 ? network : this.configuredNetwork) !== null && _a !== void 0 ? _a : mapClusterToRpcNetwork(this.cluster), "Solana mobile wallet transaction");
10719
10807
  }
10720
10808
  }
10721
10809
  SolanaMobileWalletProvider.instance = null;
@@ -10727,7 +10815,6 @@ var solanaMobileWalletProvider = /*#__PURE__*/Object.freeze({
10727
10815
  registerMobileWalletAdapter: registerMobileWalletAdapter
10728
10816
  });
10729
10817
 
10730
- const SURFNET_RPC_URL$1 = "https://surfpool.fly.dev";
10731
10818
  // @privy-io/react-auth(/solana) are OPTIONAL peer deps. They are loaded lazily
10732
10819
  // via dynamic import() rather than a static top-level import: a static import
10733
10820
  // would (a) in the ESM bundle still be a bare `import` the consumer resolves —
@@ -10760,31 +10847,28 @@ async function loadSolanaKit() {
10760
10847
  }
10761
10848
  return solanaKit;
10762
10849
  }
10763
- const getDefaultPrivyConfig = () => ({
10764
- appId: "cm4ve714908o27dk2yurpnfhd",
10765
- config: {
10766
- embeddedWallets: {
10767
- solana: {
10768
- createOnLogin: "users-without-wallets"
10769
- }
10770
- },
10771
- appearance: {
10772
- walletChainType: 'solana-only'
10773
- },
10774
- externalWallets: { solana: { connectors: privySolana.toSolanaWalletConnectors() } }
10850
+ function requirePrivyWalletConfig(privyConfig) {
10851
+ if (!privyConfig || typeof privyConfig.appId !== 'string' || privyConfig.appId.trim() === '') {
10852
+ throw new Error('Privy auth requires config.privyConfig.appId; no default Privy app is used.');
10775
10853
  }
10776
- });
10854
+ if (!privyConfig.config || typeof privyConfig.config !== 'object') {
10855
+ throw new Error('Privy auth requires config.privyConfig.config for the app-scoped Privy provider.');
10856
+ }
10857
+ return {
10858
+ appId: privyConfig.appId,
10859
+ config: privyConfig.config,
10860
+ };
10861
+ }
10777
10862
  class PrivyWalletProvider {
10778
- constructor(appName, appLogoUrl, privyConfig, networkUrl = null) {
10863
+ constructor(appName, appLogoUrl, privyConfig, networkUrl = null, configuredNetwork = null) {
10779
10864
  this.containerElement = null;
10780
- this.chainId = 'solana:mainnet';
10865
+ this.chainId = null;
10781
10866
  this.root = null;
10782
10867
  this.privyMethods = null;
10783
10868
  this.pendingLogin = null;
10784
10869
  // Resolved Solana RPC URLs (computed in the constructor; consumed in
10785
10870
  // initialize() where @solana/kit is lazily loaded to build the transports).
10786
- this.rpcDevnetUrl = SOLANA_DEVNET_RPC_URL;
10787
- this.rpcMainnetUrl = SOLANA_MAINNET_RPC_URL;
10871
+ this.configuredRpcUrl = null;
10788
10872
  // This is used to store the pending transaction until the wallet is connected for workaround for the wallet not being connected after login completion
10789
10873
  this.pendingTransaction = null;
10790
10874
  // This is used to store pending signTransaction calls until the wallet is connected
@@ -10793,41 +10877,37 @@ class PrivyWalletProvider {
10793
10877
  this.pendingSignMessage = null;
10794
10878
  // This is used to store pending signAndSubmitTransaction calls until the wallet is connected
10795
10879
  this.pendingSignAndSubmitTransaction = null;
10796
- this.networkUrl = networkUrl;
10880
+ this.networkUrl = normalizeSolanaRpcUrl(networkUrl);
10881
+ this.configuredNetwork = configuredNetwork;
10797
10882
  if (typeof window === 'undefined') {
10798
10883
  throw new Error('PrivyWalletProvider can only be instantiated in a browser environment');
10799
10884
  }
10885
+ const requiredPrivyConfig = requirePrivyWalletConfig(privyConfig);
10800
10886
  if (PrivyWalletProvider.instance) {
10801
10887
  return PrivyWalletProvider.instance;
10802
10888
  }
10803
10889
  this.containerElement = null;
10804
10890
  this.root = null;
10805
10891
  this.privyMethods = null;
10806
- this.privyConfig = privyConfig !== null && privyConfig !== void 0 ? privyConfig : getDefaultPrivyConfig();
10807
- // Only use the appName and appLogoUrl if no privyConfig is provided
10808
- if (privyConfig == null) {
10809
- if (appName != null && appName != '') {
10810
- this.privyConfig.config.appearance.landingHeader = appName;
10811
- }
10812
- if (appLogoUrl != null && appLogoUrl != '') {
10813
- this.privyConfig.config.appearance.logo = appLogoUrl;
10814
- }
10892
+ this.privyConfig = requiredPrivyConfig;
10893
+ if (!this.privyConfig.config.appearance) {
10894
+ this.privyConfig.config.appearance = {};
10895
+ }
10896
+ if (appName != null && appName != '' && !this.privyConfig.config.appearance.landingHeader) {
10897
+ this.privyConfig.config.appearance.landingHeader = appName;
10898
+ }
10899
+ if (appLogoUrl != null && appLogoUrl != '' && !this.privyConfig.config.appearance.logo) {
10900
+ this.privyConfig.config.appearance.logo = appLogoUrl;
10815
10901
  }
10816
10902
  // (externalWallets connectors are configured in initialize() once the
10817
10903
  // Privy SDK is lazily loaded — see loadPrivyModules.)
10818
10904
  // Resolve Solana RPC URLs for v3. The @solana/kit transports are built
10819
10905
  // lazily in initialize() so a non-Privy consumer never needs @solana/kit.
10820
- this.rpcDevnetUrl = SOLANA_DEVNET_RPC_URL;
10821
- this.rpcMainnetUrl = SOLANA_MAINNET_RPC_URL;
10822
- if (networkUrl != null) {
10823
- if (networkUrl.includes('mainnet')) {
10824
- this.rpcMainnetUrl = networkUrl;
10825
- this.chainId = 'solana:mainnet';
10826
- }
10827
- else if (networkUrl.includes('devnet')) {
10828
- this.rpcDevnetUrl = networkUrl;
10829
- this.chainId = 'solana:devnet';
10830
- }
10906
+ if (this.networkUrl || configuredNetwork) {
10907
+ this.configuredRpcUrl = resolveSolanaRpcUrl(this.networkUrl, configuredNetwork, "Privy Solana RPC");
10908
+ }
10909
+ if (configuredNetwork) {
10910
+ this.chainId = resolveSolanaWalletStandardChain(configuredNetwork, "Privy Solana transaction");
10831
10911
  }
10832
10912
  const existingProviders = document.querySelectorAll('[data-privy-provider]');
10833
10913
  existingProviders.forEach(el => el.remove());
@@ -10842,9 +10922,9 @@ class PrivyWalletProvider {
10842
10922
  PrivyWalletProvider.instance = this;
10843
10923
  }
10844
10924
  // Optional: Provide a static method to get the instance
10845
- static getInstance(appName, appLogoUrl, privyConfig) {
10925
+ static getInstance(appName, appLogoUrl, privyConfig, networkUrl = null, configuredNetwork = null) {
10846
10926
  if (!PrivyWalletProvider.instance) {
10847
- new PrivyWalletProvider(appName, appLogoUrl, privyConfig);
10927
+ new PrivyWalletProvider(appName, appLogoUrl, privyConfig, networkUrl, configuredNetwork);
10848
10928
  }
10849
10929
  return PrivyWalletProvider.instance;
10850
10930
  }
@@ -10854,19 +10934,17 @@ class PrivyWalletProvider {
10854
10934
  // Build the Solana RPC transports now that we're on the async path, so
10855
10935
  // @solana/kit can be lazily imported (kept out of the entry bundle).
10856
10936
  const { createSolanaRpc, createSolanaRpcSubscriptions } = await loadSolanaKit();
10857
- if (!this.privyConfig.config.solana) {
10937
+ if (this.configuredRpcUrl && this.chainId && !this.privyConfig.config.solana) {
10858
10938
  this.privyConfig.config.solana = {};
10859
10939
  }
10860
- this.privyConfig.config.solana.rpcs = {
10861
- 'solana:devnet': {
10862
- rpc: createSolanaRpc(this.rpcDevnetUrl),
10863
- rpcSubscriptions: createSolanaRpcSubscriptions(this.rpcDevnetUrl.replace('https://', 'wss://'))
10864
- },
10865
- 'solana:mainnet': {
10866
- rpc: createSolanaRpc(this.rpcMainnetUrl),
10867
- rpcSubscriptions: createSolanaRpcSubscriptions(this.rpcMainnetUrl.replace('https://', 'wss://'))
10868
- }
10869
- };
10940
+ if (this.configuredRpcUrl && this.chainId) {
10941
+ this.privyConfig.config.solana.rpcs = {
10942
+ [this.chainId]: {
10943
+ rpc: createSolanaRpc(this.configuredRpcUrl),
10944
+ rpcSubscriptions: createSolanaRpcSubscriptions(this.configuredRpcUrl.replace('https://', 'wss://'))
10945
+ }
10946
+ };
10947
+ }
10870
10948
  // Ensure externalWallets connectors are always configured — required for
10871
10949
  // useWallets().ready to resolve even when no browser extension is present.
10872
10950
  if (!this.privyConfig.config.externalWallets && privySolana) {
@@ -11202,7 +11280,7 @@ class PrivyWalletProvider {
11202
11280
  try {
11203
11281
  if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
11204
11282
  // Just sign, don't submit - return raw signed bytes (same as original runTransaction)
11205
- const signedTx = await this.signTransactionRaw(tx, privyWallet);
11283
+ const signedTx = await this.signTransactionRaw(tx, privyWallet, solTransactionData.network);
11206
11284
  return {
11207
11285
  signedTransaction: signedTx, // Raw Uint8Array from Privy
11208
11286
  blockNumber: 0,
@@ -11211,7 +11289,7 @@ class PrivyWalletProvider {
11211
11289
  };
11212
11290
  }
11213
11291
  // Sign and submit using shared helper
11214
- const { signature, txInfo } = await this.signAndSubmitInternal(tx, privyWallet, rpcUrl, connection);
11292
+ const { signature, txInfo } = await this.signAndSubmitInternal(tx, privyWallet, rpcUrl, connection, solTransactionData.network);
11215
11293
  return {
11216
11294
  transactionSignature: signature,
11217
11295
  blockNumber: (txInfo === null || txInfo === void 0 ? void 0 : txInfo.slot) || 0,
@@ -11383,26 +11461,25 @@ class PrivyWalletProvider {
11383
11461
  }
11384
11462
  // ============ Private Helpers ============
11385
11463
  getRpcUrl(network) {
11386
- if (this.networkUrl) {
11387
- return this.networkUrl;
11388
- }
11389
- if (network === 'solana_devnet') {
11390
- return SOLANA_DEVNET_RPC_URL;
11391
- }
11392
- else if (network === 'solana_mainnet') {
11393
- return SOLANA_MAINNET_RPC_URL;
11464
+ return resolveSolanaRpcUrl(this.networkUrl, network !== null && network !== void 0 ? network : this.configuredNetwork, "Privy Solana transaction");
11465
+ }
11466
+ getChainId(network) {
11467
+ if (network) {
11468
+ return resolveSolanaWalletStandardChain(network, "Privy Solana transaction");
11394
11469
  }
11395
- else if (network === 'surfnet') {
11396
- return SURFNET_RPC_URL$1;
11470
+ if (this.chainId)
11471
+ return this.chainId;
11472
+ if (this.configuredNetwork) {
11473
+ return resolveSolanaWalletStandardChain(this.configuredNetwork, "Privy Solana transaction");
11397
11474
  }
11398
- return SOLANA_MAINNET_RPC_URL; // default to mainnet
11475
+ throw new Error("Privy Solana transaction requires config.chain as solana_devnet, solana_mainnet, or surfnet.");
11399
11476
  }
11400
11477
  /**
11401
11478
  * Internal sign transaction - serializes and signs via Privy
11402
11479
  * Returns the raw result from Privy (Uint8Array)
11403
11480
  * This mirrors exactly what runTransaction was doing
11404
11481
  */
11405
- async signTransactionRaw(transaction, privyWallet) {
11482
+ async signTransactionRaw(transaction, privyWallet, network) {
11406
11483
  var _a;
11407
11484
  // Serialize the transaction
11408
11485
  // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
@@ -11418,7 +11495,7 @@ class PrivyWalletProvider {
11418
11495
  const result = await ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.signTransaction({
11419
11496
  transaction: serializedForSign,
11420
11497
  wallet: privyWallet,
11421
- chain: this.chainId
11498
+ chain: this.getChainId(network)
11422
11499
  }));
11423
11500
  // Privy returns { signedTransaction: Uint8Array }, unwrap it
11424
11501
  const signedTx = (result === null || result === void 0 ? void 0 : result.signedTransaction) || result;
@@ -11463,13 +11540,13 @@ class PrivyWalletProvider {
11463
11540
  * For Surfnet: sign with signTransactionRaw, then sendRawTransaction
11464
11541
  * For non-Surfnet: use Privy's signAndSendTransaction (combined operation)
11465
11542
  */
11466
- async signAndSubmitInternal(transaction, privyWallet, rpcUrl, connection) {
11543
+ async signAndSubmitInternal(transaction, privyWallet, rpcUrl, connection, network) {
11467
11544
  var _a;
11468
- const isSurfnet = rpcUrl === SURFNET_RPC_URL$1;
11545
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
11469
11546
  let signature;
11470
11547
  if (isSurfnet) {
11471
11548
  // For Surfnet: sign with signTransactionRaw, then sendRawTransaction
11472
- const signedTx = await this.signTransactionRaw(transaction, privyWallet);
11549
+ const signedTx = await this.signTransactionRaw(transaction, privyWallet, network);
11473
11550
  signature = await connection.sendRawTransaction(signedTx);
11474
11551
  }
11475
11552
  else {
@@ -11487,7 +11564,7 @@ class PrivyWalletProvider {
11487
11564
  const result = await ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.useSendTransactionSolana.signAndSendTransaction({
11488
11565
  transaction: serializedTx,
11489
11566
  wallet: privyWallet,
11490
- chain: this.chainId
11567
+ chain: this.getChainId(network)
11491
11568
  }));
11492
11569
  // Handle case where signature might be bytes instead of string
11493
11570
  const rawSig = result.signature;
@@ -11554,16 +11631,7 @@ class PrivyWalletProvider {
11554
11631
  }
11555
11632
  let privyWallet = this.privyMethods.wallets.find((wallet) => wallet.address === sessionAddress);
11556
11633
  if (!privyWallet) {
11557
- // Session address is not a privy wallet, just default to the first wallet
11558
- const accessToken = await this.privyMethods.getAccessToken();
11559
- await this.createSession(this.privyMethods.wallets[0].address, accessToken, this.privyMethods.identityToken);
11560
- setCurrentUser({ address: this.privyMethods.wallets[0].address, provider: this });
11561
- const session = await core.getActiveSessionManager().getSession();
11562
- sessionAddress = session === null || session === void 0 ? void 0 : session.address;
11563
- if (!sessionAddress) {
11564
- throw new Error('No wallet connected or logged in to sign message');
11565
- }
11566
- privyWallet = this.privyMethods.wallets[0];
11634
+ throw new Error('Active Privy wallets do not include the authenticated session wallet; please log in again.');
11567
11635
  }
11568
11636
  // Use the Privy signMessage hook for Solana wallets
11569
11637
  // The message needs to be passed as a Uint8Array
@@ -11593,22 +11661,21 @@ class PrivyWalletProvider {
11593
11661
  // Privy-specific token verification — it arrives as a Solana signature and is
11594
11662
  // recorded server-side as authMethod 'phantom'.
11595
11663
  async createSession(address, _accessToken, _idToken) {
11596
- var _a, _b, _c, _d, _e, _f, _g;
11597
- // Resolve the Privy wallet for this address (fall back to the first wallet).
11598
- const privyWallet = (_c = (_b = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets) === null || _b === void 0 ? void 0 : _b.find((w) => w.address === address)) !== null && _c !== void 0 ? _c : (_e = (_d = this.privyMethods) === null || _d === void 0 ? void 0 : _d.wallets) === null || _e === void 0 ? void 0 : _e[0];
11664
+ var _a, _b, _c, _d;
11665
+ const privyWallet = (_b = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets) === null || _b === void 0 ? void 0 : _b.find((w) => w.address === address);
11599
11666
  if (!privyWallet) {
11600
- throw new Error('No Privy Solana wallet available to mint a session.');
11667
+ throw new Error('No Privy Solana wallet matching the requested session address is available.');
11601
11668
  }
11602
11669
  const nonce = await core.genAuthNonce();
11603
11670
  const message = await core.genSolanaMessage(address, nonce);
11604
11671
  const messageBytes = getPlatform().textEncode(message);
11605
11672
  // Low-level Privy sign hook — signs WITHOUT touching the session (the public
11606
11673
  // signMessage() bootstraps sessions, which would recurse here).
11607
- const signResult = await ((_f = this.privyMethods) === null || _f === void 0 ? void 0 : _f.signMessage({
11674
+ const signResult = await ((_c = this.privyMethods) === null || _c === void 0 ? void 0 : _c.signMessage({
11608
11675
  message: messageBytes,
11609
11676
  wallet: privyWallet,
11610
11677
  }));
11611
- const signatureBytes = (_g = signResult === null || signResult === void 0 ? void 0 : signResult.signature) !== null && _g !== void 0 ? _g : signResult;
11678
+ const signatureBytes = (_d = signResult === null || signResult === void 0 ? void 0 : signResult.signature) !== null && _d !== void 0 ? _d : signResult;
11612
11679
  // base64-encoded detached signature (matches Phantom + guest providers).
11613
11680
  const signature = bufferExports.Buffer.from(signatureBytes).toString('base64');
11614
11681
  const createSessionResult = await core.createSessionWithSignature(address, message, signature);
@@ -11690,7 +11757,6 @@ var privyWalletProvider = /*#__PURE__*/Object.freeze({
11690
11757
  * to host Privy's React context, this provider expects the RN app itself
11691
11758
  * to render <PrivyProvider> and then bridge the hooks via setPrivyMethods().
11692
11759
  */
11693
- const SURFNET_RPC_URL = 'https://surfpool.fly.dev';
11694
11760
  // -----------------------------------------------------------------------
11695
11761
  // Provider implementation
11696
11762
  // -----------------------------------------------------------------------
@@ -11698,7 +11764,7 @@ class PrivyExpoProvider {
11698
11764
  constructor(appId, networkUrl = null) {
11699
11765
  this.privyMethods = null;
11700
11766
  this.appId = appId;
11701
- this.networkUrl = networkUrl;
11767
+ this.networkUrl = normalizeSolanaRpcUrl(networkUrl);
11702
11768
  }
11703
11769
  /**
11704
11770
  * Bridge Privy hooks from the app's React tree into this provider.
@@ -11983,15 +12049,7 @@ class PrivyExpoProvider {
11983
12049
  return { signature, txInfo };
11984
12050
  }
11985
12051
  getRpcUrl(network) {
11986
- if (this.networkUrl)
11987
- return this.networkUrl;
11988
- if (network === 'solana_devnet')
11989
- return SOLANA_DEVNET_RPC_URL;
11990
- if (network === 'solana_mainnet')
11991
- return SOLANA_MAINNET_RPC_URL;
11992
- if (network === 'surfnet')
11993
- return SURFNET_RPC_URL;
11994
- return SOLANA_MAINNET_RPC_URL;
12052
+ return resolveSolanaRpcUrl(this.networkUrl, network, "Privy Expo Solana transaction");
11995
12053
  }
11996
12054
  async ensureReady(timeoutMs = 15000) {
11997
12055
  if (!this.privyMethods) {