@bounded-sh/client 0.0.19 → 0.0.21

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 (31) hide show
  1. package/README.md +2 -2
  2. package/dist/auth/providers/offchain-auth-provider.d.ts +2 -4
  3. package/dist/index.d.ts +0 -1
  4. package/dist/index.js +150 -214
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +151 -213
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/{index.native-DI_Xgv-n.js → index.native-DdKzAUjN.js} +154 -218
  9. package/dist/index.native-DdKzAUjN.js.map +1 -0
  10. package/dist/{index.native-DWI_i6-6.mjs → index.native-N3xLU862.mjs} +155 -217
  11. package/dist/index.native-N3xLU862.mjs.map +1 -0
  12. package/dist/index.native.d.ts +0 -1
  13. package/dist/index.native.js +1 -3
  14. package/dist/index.native.js.map +1 -1
  15. package/dist/index.native.mjs +1 -1
  16. package/dist/{phantom-wallet-provider-DDwgNMg_.mjs → phantom-wallet-provider-DcE4A2_e.mjs} +2 -2
  17. package/dist/{phantom-wallet-provider-DDwgNMg_.mjs.map → phantom-wallet-provider-DcE4A2_e.mjs.map} +1 -1
  18. package/dist/{phantom-wallet-provider-fyOrJZP6.js → phantom-wallet-provider-Dz9lQvNv.js} +2 -2
  19. package/dist/{phantom-wallet-provider-fyOrJZP6.js.map → phantom-wallet-provider-Dz9lQvNv.js.map} +1 -1
  20. package/dist/{privy-wallet-provider-BIr9lDS7.js → privy-wallet-provider-DUvjxNXK.js} +3 -3
  21. package/dist/{privy-wallet-provider-BIr9lDS7.js.map → privy-wallet-provider-DUvjxNXK.js.map} +1 -1
  22. package/dist/{privy-wallet-provider-D7VoQCYf.mjs → privy-wallet-provider-oG3o5vko.mjs} +3 -3
  23. package/dist/{privy-wallet-provider-D7VoQCYf.mjs.map → privy-wallet-provider-oG3o5vko.mjs.map} +1 -1
  24. package/dist/{solana-mobile-wallet-provider-Cush-URL.js → solana-mobile-wallet-provider-DdBoG6c2.js} +2 -2
  25. package/dist/{solana-mobile-wallet-provider-Cush-URL.js.map → solana-mobile-wallet-provider-DdBoG6c2.js.map} +1 -1
  26. package/dist/{solana-mobile-wallet-provider-DgcGxDoL.mjs → solana-mobile-wallet-provider-aS60_GZR.mjs} +2 -2
  27. package/dist/{solana-mobile-wallet-provider-DgcGxDoL.mjs.map → solana-mobile-wallet-provider-aS60_GZR.mjs.map} +1 -1
  28. package/package.json +2 -2
  29. package/dist/auth/providers/mock-auth-provider.d.ts +0 -49
  30. package/dist/index.native-DI_Xgv-n.js.map +0 -1
  31. package/dist/index.native-DWI_i6-6.mjs.map +0 -1
@@ -156,142 +156,11 @@ function detectAndroid() {
156
156
  return false;
157
157
  }
158
158
 
159
- // Default test wallet address (Solana devnet address)
160
- const DEFAULT_TEST_ADDRESS = 'HKbZbRR7jWWR5VRN8KFjvTCHEzJQgameYxKQxh2gPoof';
161
- // Session storage key to track if user explicitly called login()
162
- const EXPLICIT_LOGIN_KEY = 'mock-auth-explicit-login';
163
- /**
164
- * MockAuthProvider bypasses real wallet authentication for testing purposes.
165
- * Uses session storage to simulate logged-in user, with fallback to default test address.
166
- *
167
- * This is enabled by passing mockAuth: true to init()
168
- */
169
- class MockAuthProvider {
170
- /**
171
- * Mock login - reads user from session storage or uses default test address
172
- */
173
- async login() {
174
- let address = getPlatform().sessionStorage.getItem('test-user-address');
175
- if (!address) {
176
- address = DEFAULT_TEST_ADDRESS;
177
- // Store default address in session storage so it gets used in API calls
178
- getPlatform().sessionStorage.setItem('test-user-address', DEFAULT_TEST_ADDRESS);
179
- console.log('[MockAuth] Using default test address:', address);
180
- }
181
- // Mark that user explicitly called login() - allows restoreSession on refresh
182
- getPlatform().sessionStorage.setItem(EXPLICIT_LOGIN_KEY, 'true');
183
- console.log('[MockAuth] Mock login successful:', address);
184
- return {
185
- address,
186
- provider: this
187
- };
188
- }
189
- /**
190
- * Mock transaction - returns fake signature without actual blockchain interaction
191
- * The real transaction will be handled by the backend using test headers
192
- */
193
- async runTransaction(evmTransactionData, solTransactionData, options) {
194
- const address = getPlatform().sessionStorage.getItem('test-user-address') || DEFAULT_TEST_ADDRESS;
195
- // Generate a fake transaction signature
196
- const fakeSignature = `mock_tx_${Math.random().toString(36).substring(2, 15)}`;
197
- console.log('[MockAuth] Mock transaction executed:', {
198
- address,
199
- signature: fakeSignature,
200
- evmTx: evmTransactionData,
201
- solTx: solTransactionData
202
- });
203
- return {
204
- transactionSignature: fakeSignature,
205
- signedTransaction: fakeSignature,
206
- blockNumber: 0,
207
- gasUsed: '0'
208
- };
209
- }
210
- /**
211
- * Mock message signing
212
- */
213
- async signMessage(message) {
214
- const address = getPlatform().sessionStorage.getItem('test-user-address') || DEFAULT_TEST_ADDRESS;
215
- // Generate a fake signature
216
- const fakeSignature = `mock_sig_${Math.random().toString(36).substring(2, 15)}`;
217
- console.log('[MockAuth] Mock message signed:', {
218
- address,
219
- message,
220
- signature: fakeSignature
221
- });
222
- return fakeSignature;
223
- }
224
- async signMessageMock(message) {
225
- const address = getPlatform().sessionStorage.getItem('test-user-address') || DEFAULT_TEST_ADDRESS;
226
- const signature = `mock_sig_${Math.random().toString(36).substring(2, 15)}`;
227
- console.log('[MockAuth] Mock message signed:', {
228
- address,
229
- message,
230
- signature
231
- });
232
- return signature;
233
- }
234
- /**
235
- * Mock transaction signing - returns the transaction as-is (no actual signing)
236
- */
237
- async signTransaction(transaction) {
238
- console.log('[MockAuth] Mock transaction signing (no-op)');
239
- return transaction;
240
- }
241
- /**
242
- * Sign and submit transaction - not supported in mock environment.
243
- * See the real providers (PhantomWalletProvider, SolanaKeypairProvider)
244
- * for the full implementation with blockhash handling and feePayer support.
245
- */
246
- async signAndSubmitTransaction(_transaction, _feePayer) {
247
- throw new Error('signAndSubmitTransaction is not supported in the mock environment');
248
- }
249
- /**
250
- * Restore session - only restores if user previously called login() explicitly.
251
- * This prevents auto-login on first page load, but allows session persistence after login.
252
- */
253
- async restoreSession() {
254
- const explicitlyLoggedIn = getPlatform().sessionStorage.getItem(EXPLICIT_LOGIN_KEY);
255
- if (!explicitlyLoggedIn) {
256
- console.log('[MockAuth] No explicit login found. Call login() to authenticate.');
257
- return null;
258
- }
259
- const address = getPlatform().sessionStorage.getItem('test-user-address');
260
- if (!address) {
261
- console.log('[MockAuth] No previous session found');
262
- return null;
263
- }
264
- console.log('[MockAuth] Session restored:', address);
265
- return {
266
- address,
267
- provider: this
268
- };
269
- }
270
- /**
271
- * Mock logout - clears test user from session storage
272
- */
273
- async logout() {
274
- getPlatform().sessionStorage.removeItem('test-user-address');
275
- getPlatform().sessionStorage.removeItem('test-user-id');
276
- getPlatform().sessionStorage.removeItem(EXPLICIT_LOGIN_KEY);
277
- console.log('[MockAuth] Mock logout successful');
278
- }
279
- /**
280
- * Get native wallet methods (not needed for mock auth)
281
- */
282
- async getNativeMethods() {
283
- return {
284
- // Return empty object - no native methods needed for mock auth
285
- };
286
- }
287
- }
288
-
289
159
  /**
290
160
  * OffchainAuthProvider wraps a real auth provider (e.g., Phantom) for the poofnet environment.
291
161
  *
292
- * For signMessageMock, this shows a custom confirmation modal and then delegates
293
- * to the wrapped provider for a real detached signature over the exact offchain
294
- * transaction message.
162
+ * signMessage shows a custom confirmation modal and then delegates to the wrapped
163
+ * provider for a real detached signature over the exact offchain transaction message.
295
164
  */
296
165
  class OffchainAuthProvider {
297
166
  constructor(wrappedProvider, config = {}) {
@@ -342,13 +211,7 @@ class OffchainAuthProvider {
342
211
  }
343
212
  // ============ signMessage delegates to wrapped provider ============
344
213
  async signMessage(message) {
345
- // Delegate to wrapped provider for real wallet signing
346
- return this.wrappedProvider.signMessage(message);
347
- }
348
- // ============ Mock signMessage with Custom Modal for Offchain Transactions ============
349
- async signMessageMock(message) {
350
214
  var _a, _b, _c, _d, _e, _f;
351
- // Callback: signing started
352
215
  (_b = (_a = this.config).onSigningStart) === null || _b === void 0 ? void 0 : _b.call(_a);
353
216
  try {
354
217
  // On RN (no DOM), auto-confirm — there's no modal to show.
@@ -365,7 +228,6 @@ class OffchainAuthProvider {
365
228
  return signature;
366
229
  }
367
230
  catch (error) {
368
- // Callback: signing error
369
231
  (_f = (_e = this.config).onSigningError) === null || _f === void 0 ? void 0 : _f.call(_e, error);
370
232
  throw error;
371
233
  }
@@ -4103,13 +3965,33 @@ function createEmailModalTree() {
4103
3965
  close.type = 'button';
4104
3966
  close.textContent = '×';
4105
3967
  card.appendChild(close);
3968
+ // Brand row — the real Bounded mark (same geometry as bounded.sh) + wordmark.
4106
3969
  const brand = document.createElement('div');
4107
3970
  brand.className = 'ba-brand';
4108
- const dot = document.createElement('span');
4109
- dot.className = 'ba-dot';
4110
- brand.appendChild(dot);
4111
- brand.appendChild(document.createTextNode(' Sign in'));
3971
+ const mark = document.createElement('span');
3972
+ mark.className = 'ba-mark';
3973
+ mark.setAttribute('aria-hidden', 'true');
3974
+ mark.innerHTML =
3975
+ '<svg width="24" height="24" viewBox="0 0 32 32" fill="none">' +
3976
+ '<path class="ba-c ba-c1" d="M16 5 H5 V16"/>' +
3977
+ '<path class="ba-c ba-c2" d="M16 5 H27 V16"/>' +
3978
+ '<path class="ba-c ba-c3" d="M5 16 V27 H16"/>' +
3979
+ '<path class="ba-c ba-c4" d="M27 16 V27 H16"/>' +
3980
+ '</svg>';
3981
+ brand.appendChild(mark);
3982
+ const word = document.createElement('span');
3983
+ word.className = 'ba-word';
3984
+ word.textContent = 'bounded';
3985
+ brand.appendChild(word);
4112
3986
  card.appendChild(brand);
3987
+ const title = document.createElement('h1');
3988
+ title.className = 'ba-title';
3989
+ title.textContent = 'Sign in';
3990
+ card.appendChild(title);
3991
+ const sub = document.createElement('p');
3992
+ sub.className = 'ba-subtitle';
3993
+ sub.textContent = 'Continue with your email — no wallet needed.';
3994
+ card.appendChild(sub);
4113
3995
  const emailStep = document.createElement('div');
4114
3996
  emailStep.id = 'ba-email-step';
4115
3997
  card.appendChild(emailStep);
@@ -4130,7 +4012,7 @@ function createEmailModalTree() {
4130
4012
  emailButton.id = 'ba-email-btn';
4131
4013
  emailButton.className = 'ba-btn';
4132
4014
  emailButton.type = 'button';
4133
- emailButton.textContent = 'Continue';
4015
+ emailButton.textContent = 'Continue with email';
4134
4016
  emailStep.appendChild(emailButton);
4135
4017
  const otpStep = document.createElement('div');
4136
4018
  otpStep.id = 'ba-otp-step';
@@ -4175,37 +4057,67 @@ function createEmailModalTree() {
4175
4057
  card.appendChild(foot);
4176
4058
  return root;
4177
4059
  }
4060
+ // Design language matches the hosted Bounded login (auth.bounded.sh) and bounded.sh:
4061
+ // dark editorial panel, green accent, Schibsted Grotesk / Newsreader / JetBrains Mono,
4062
+ // the Bounded mark drawing itself in. Fonts load best-effort (scoped @import); every
4063
+ // rule has a system fallback so the modal looks right even if Google Fonts is blocked.
4064
+ // All selectors are scoped under #bounded-auth-modal so we never leak into the host page.
4178
4065
  const MODAL_CSS = `
4179
- #bounded-auth-modal .ba-overlay{position:fixed;inset:0;background:rgba(8,10,18,.62);backdrop-filter:blur(4px);
4066
+ @import url('https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,500&family=Schibsted+Grotesk:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
4067
+ #bounded-auth-modal{--ba-bg:#0a0a0b;--ba-panel:#0e0f11;--ba-inset:#060607;--ba-raise:#131416;
4068
+ --ba-line:rgba(232,230,222,.08);--ba-line-strong:rgba(232,230,222,.16);
4069
+ --ba-text:#e8e6de;--ba-dim:#9b9991;--ba-faint:#85837c;--ba-green:#58c98f;
4070
+ --ba-green-bg:rgba(88,201,143,.09);--ba-green-line:rgba(88,201,143,.28);--ba-red:#ec8488;
4071
+ --ba-body:'Schibsted Grotesk',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
4072
+ --ba-display:'Newsreader','Iowan Old Style',Georgia,serif;
4073
+ --ba-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace;}
4074
+ #bounded-auth-modal .ba-overlay{position:fixed;inset:0;background:rgba(6,6,7,.66);backdrop-filter:blur(4px);
4180
4075
  display:flex;align-items:center;justify-content:center;z-index:2147483000;opacity:1;transition:opacity .16s ease;
4181
- font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;padding:16px;}
4076
+ font-family:var(--ba-body);padding:16px;}
4182
4077
  #bounded-auth-modal .ba-overlay.out{opacity:0;}
4183
- #bounded-auth-modal .ba-card{width:100%;max-width:380px;background:#0f1117;color:#f4f5f7;border:1px solid #232838;
4184
- border-radius:18px;padding:24px 22px 18px;box-shadow:0 24px 70px rgba(0,0,0,.5);position:relative;
4185
- animation:ba-in .18s ease;}
4186
- @keyframes ba-in{from{transform:translateY(10px);opacity:.6}to{transform:translateY(0);opacity:1}}
4187
- #bounded-auth-modal .ba-x{position:absolute;top:12px;right:12px;width:30px;height:30px;border:none;background:#1a1e2b;
4188
- color:#9aa3b2;border-radius:9px;font-size:20px;line-height:1;cursor:pointer;}
4189
- #bounded-auth-modal .ba-x:hover{background:#222838;color:#fff;}
4190
- #bounded-auth-modal .ba-brand{display:flex;align-items:center;gap:8px;font-weight:600;font-size:15px;margin:0 0 18px;}
4191
- #bounded-auth-modal .ba-dot{width:10px;height:10px;border-radius:50%;background:linear-gradient(135deg,#8b5cf6,#22d3ee);}
4192
- #bounded-auth-modal .ba-label{display:block;font-size:13px;color:#aab2c0;margin:0 0 8px;}
4193
- #bounded-auth-modal .ba-em{color:#fff;font-weight:600;}
4194
- #bounded-auth-modal .ba-input{width:100%;box-sizing:border-box;background:#171b26;border:1px solid #2a3040;color:#fff;
4195
- border-radius:11px;padding:13px 14px;font-size:16px;outline:none;transition:border-color .12s;}
4196
- #bounded-auth-modal .ba-input:focus{border-color:#7c5cff;}
4197
- #bounded-auth-modal .ba-code{letter-spacing:8px;text-align:center;font-size:22px;font-variant-numeric:tabular-nums;}
4198
- #bounded-auth-modal .ba-btn{width:100%;margin-top:12px;background:linear-gradient(135deg,#7c5cff,#5b8cff);color:#fff;
4199
- border:none;border-radius:11px;padding:13px;font-size:15px;font-weight:600;cursor:pointer;transition:filter .12s;}
4200
- #bounded-auth-modal .ba-btn:hover{filter:brightness(1.08);}
4201
- #bounded-auth-modal .ba-btn:disabled{opacity:.6;cursor:default;}
4202
- #bounded-auth-modal .ba-link{width:100%;margin-top:10px;background:none;border:none;color:#8aa0c6;font-size:13px;cursor:pointer;}
4203
- #bounded-auth-modal .ba-link:hover{color:#bcd0f0;}
4204
- #bounded-auth-modal .ba-msg{min-height:18px;margin-top:10px;font-size:13px;color:#8aa0c6;text-align:center;}
4205
- #bounded-auth-modal .ba-msg.err{color:#ff8a8a;}
4206
- #bounded-auth-modal .ba-foot{margin-top:14px;text-align:center;font-size:11px;color:#5a6273;}
4078
+ #bounded-auth-modal *{box-sizing:border-box;}
4079
+ #bounded-auth-modal .ba-card{width:100%;max-width:372px;background:var(--ba-panel);color:var(--ba-text);
4080
+ border:1px solid var(--ba-line);border-radius:12px;padding:28px 28px 22px;position:relative;
4081
+ box-shadow:0 1px 0 rgba(232,230,222,.03) inset,0 30px 80px -40px rgba(0,0,0,.8);animation:ba-in .18s ease;}
4082
+ @keyframes ba-in{from{transform:translateY(8px);opacity:.5}to{transform:translateY(0);opacity:1}}
4083
+ #bounded-auth-modal .ba-x{position:absolute;top:14px;right:14px;width:28px;height:28px;border:1px solid var(--ba-line);
4084
+ background:var(--ba-raise);color:var(--ba-faint);border-radius:7px;font-size:18px;line-height:1;cursor:pointer;
4085
+ transition:color .15s,border-color .15s;}
4086
+ #bounded-auth-modal .ba-x:hover{color:var(--ba-text);border-color:var(--ba-faint);}
4087
+ #bounded-auth-modal .ba-brand{display:flex;align-items:center;gap:10px;margin:0 0 24px;}
4088
+ #bounded-auth-modal .ba-mark{display:flex;color:var(--ba-text);}
4089
+ #bounded-auth-modal .ba-mark svg{overflow:visible;display:block;}
4090
+ #bounded-auth-modal .ba-c{stroke:currentColor;stroke-width:2.4;fill:none;}
4091
+ @media (prefers-reduced-motion:no-preference){
4092
+ #bounded-auth-modal .ba-c{stroke-dasharray:23;stroke-dashoffset:23;animation:ba-draw .4s cubic-bezier(.45,0,.2,1) forwards;}
4093
+ #bounded-auth-modal .ba-c1{animation-delay:.1s}#bounded-auth-modal .ba-c2{animation-delay:.38s}
4094
+ #bounded-auth-modal .ba-c3{animation-delay:.66s}#bounded-auth-modal .ba-c4{animation-delay:.94s}}
4095
+ @keyframes ba-draw{to{stroke-dashoffset:0}}
4096
+ #bounded-auth-modal .ba-word{font-family:var(--ba-body);font-weight:500;font-size:15px;letter-spacing:.2px;color:var(--ba-text);}
4097
+ #bounded-auth-modal .ba-title{font-family:var(--ba-display);font-weight:400;font-size:25px;letter-spacing:-.01em;margin:0 0 5px;}
4098
+ #bounded-auth-modal .ba-subtitle{color:var(--ba-dim);font-size:14px;margin:0 0 22px;}
4099
+ #bounded-auth-modal .ba-label{display:block;font-size:12px;color:var(--ba-dim);margin:0 0 7px;}
4100
+ #bounded-auth-modal .ba-em{color:var(--ba-text);font-weight:600;}
4101
+ #bounded-auth-modal .ba-input{width:100%;background:var(--ba-inset);border:1px solid var(--ba-line-strong);color:var(--ba-text);
4102
+ border-radius:6px;padding:11px 13px;font-family:var(--ba-body);font-size:15px;outline:none;transition:border-color .15s,box-shadow .15s;}
4103
+ #bounded-auth-modal .ba-input::placeholder{color:var(--ba-faint);}
4104
+ #bounded-auth-modal .ba-input:focus{border-color:var(--ba-green-line);box-shadow:0 0 0 3px var(--ba-green-bg);}
4105
+ #bounded-auth-modal .ba-code{font-family:var(--ba-mono);letter-spacing:8px;text-align:center;font-size:21px;padding-left:8px;}
4106
+ #bounded-auth-modal .ba-btn{width:100%;margin-top:16px;background:var(--ba-text);color:var(--ba-bg);
4107
+ border:0;border-radius:6px;padding:12px;font-family:var(--ba-body);font-size:14px;font-weight:600;cursor:pointer;
4108
+ transition:opacity .15s,transform .04s;}
4109
+ #bounded-auth-modal .ba-btn:hover{opacity:.9;}
4110
+ #bounded-auth-modal .ba-btn:active{transform:translateY(.5px);}
4111
+ #bounded-auth-modal .ba-btn:disabled{opacity:.45;cursor:default;}
4112
+ #bounded-auth-modal .ba-link{width:100%;margin-top:14px;background:none;border:none;color:var(--ba-dim);
4113
+ font-family:var(--ba-body);font-size:12.5px;cursor:pointer;}
4114
+ #bounded-auth-modal .ba-link:hover{color:var(--ba-text);}
4115
+ #bounded-auth-modal .ba-msg{min-height:16px;margin-top:16px;font-size:12.5px;color:var(--ba-dim);text-align:center;}
4116
+ #bounded-auth-modal .ba-msg.err{color:var(--ba-red);}
4117
+ #bounded-auth-modal .ba-foot{margin-top:26px;padding-top:16px;border-top:1px solid var(--ba-line);
4118
+ text-align:center;font-size:11px;color:var(--ba-faint);}
4207
4119
  #bounded-auth-modal .hidden{display:none;}
4208
- @media (max-width:480px){#bounded-auth-modal .ba-card{max-width:none;border-radius:16px;}}`;
4120
+ @media (max-width:480px){#bounded-auth-modal .ba-card{max-width:none;}}`;
4209
4121
 
4210
4122
  const SURFNET_RPC_URL = "https://surfpool.fly.dev";
4211
4123
  const SUPPORTED_SOLANA_NETWORKS = new Set([
@@ -4252,6 +4164,7 @@ function resolveSolanaRpcUrl(explicitRpcUrl, network, context) {
4252
4164
  }
4253
4165
 
4254
4166
  const PKCE_STORE_KEY = 'bounded.oidc.pkce';
4167
+ const STORED_AUTH_METHOD_KEY$1 = 'bounded_last_auth_method';
4255
4168
  // Active session store (Web on web, RN on React Native) — selected by config,
4256
4169
  // not by `typeof window` (truthy on RN). OIDC redirect/popup is web-only, but the
4257
4170
  // session it mints is read back through this same selector everywhere.
@@ -4546,6 +4459,10 @@ async function exchangeCode(code, verifier, redirectUri) {
4546
4459
  const refreshToken = tokenField(data, 'refresh_token', 'refreshToken');
4547
4460
  const user = userFromIdToken(idToken);
4548
4461
  await sessionManager().storeSession(String(user.address || ''), accessToken, idToken, refreshToken, base);
4462
+ try {
4463
+ getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$1, 'email');
4464
+ }
4465
+ catch ( /* storage unavailable */_b) { /* storage unavailable */ }
4549
4466
  setCurrentUser(user);
4550
4467
  setAuthProviderInstance(oidcProviderSingleton);
4551
4468
  return user;
@@ -4556,7 +4473,10 @@ async function exchangeCode(code, verifier, redirectUri) {
4556
4473
  // (react-dom) when this module is imported on RN.
4557
4474
  let currentAuthProvider = null;
4558
4475
  let currentAuthMethod = null;
4476
+ let currentAuthProviderConfigKey = null;
4559
4477
  let initConfig = null;
4478
+ const objectIdentityKeys = new WeakMap();
4479
+ let nextObjectIdentityKey = 1;
4560
4480
  // --- localStorage helpers: track which auth method created the active session ---
4561
4481
  const STORED_AUTH_METHOD_KEY = 'bounded_last_auth_method';
4562
4482
  function getStoredAuthMethod() {
@@ -4580,6 +4500,51 @@ function setStoredAuthMethod(method) {
4580
4500
  // storage might not be available
4581
4501
  }
4582
4502
  }
4503
+ function objectIdentityKey(value) {
4504
+ if (!value || (typeof value !== 'object' && typeof value !== 'function'))
4505
+ return null;
4506
+ const obj = value;
4507
+ let id = objectIdentityKeys.get(obj);
4508
+ if (!id) {
4509
+ id = nextObjectIdentityKey++;
4510
+ objectIdentityKeys.set(obj, id);
4511
+ }
4512
+ return `object:${id}`;
4513
+ }
4514
+ function stableConfigValue(value, seen = new WeakSet()) {
4515
+ if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')
4516
+ return value;
4517
+ if (typeof value === 'function')
4518
+ return '[function]';
4519
+ if (Array.isArray(value))
4520
+ return value.map((item) => stableConfigValue(item, seen));
4521
+ if (typeof value === 'object') {
4522
+ if (seen.has(value))
4523
+ return '[circular]';
4524
+ seen.add(value);
4525
+ const out = {};
4526
+ for (const key of Object.keys(value).sort()) {
4527
+ out[key] = stableConfigValue(value[key], seen);
4528
+ }
4529
+ seen.delete(value);
4530
+ return out;
4531
+ }
4532
+ return String(value);
4533
+ }
4534
+ function authProviderConfigKey(config) {
4535
+ var _a, _b, _c, _d, _e, _f, _g, _h;
4536
+ return JSON.stringify({
4537
+ authMethod: (_a = config.authMethod) !== null && _a !== void 0 ? _a : null,
4538
+ chain: (_b = config.chain) !== null && _b !== void 0 ? _b : null,
4539
+ rpcUrl: normalizeSolanaRpcUrl(config.rpcUrl),
4540
+ name: (_c = config.name) !== null && _c !== void 0 ? _c : null,
4541
+ logoUrl: (_d = config.logoUrl) !== null && _d !== void 0 ? _d : null,
4542
+ phantomConfig: stableConfigValue((_e = config.phantomConfig) !== null && _e !== void 0 ? _e : null),
4543
+ privyConfig: stableConfigValue((_f = config.privyConfig) !== null && _f !== void 0 ? _f : null),
4544
+ mobileWalletConfig: stableConfigValue((_g = config.mobileWalletConfig) !== null && _g !== void 0 ? _g : null),
4545
+ privyExpoProvider: objectIdentityKey((_h = config.privyExpoProvider) !== null && _h !== void 0 ? _h : null),
4546
+ });
4547
+ }
4583
4548
  /**
4584
4549
  * Clears the session if it was created by a different auth method.
4585
4550
  * Returns true if the session was cleared, false if the session is compatible.
@@ -4605,17 +4570,17 @@ function clearIncompatibleSession() {
4605
4570
  // Lazy loaders for web-only providers.
4606
4571
  // Using dynamic import() ensures Metro (RN) never resolves these modules.
4607
4572
  async function loadPhantomWalletProvider() {
4608
- const mod = await import('./phantom-wallet-provider-DDwgNMg_.mjs');
4573
+ const mod = await import('./phantom-wallet-provider-DcE4A2_e.mjs');
4609
4574
  return { PhantomWalletProvider: mod.PhantomWalletProvider };
4610
4575
  }
4611
4576
  // Web Privy provider (depends on react-dom + @privy-io/react-auth). Lazy so Metro
4612
4577
  // never bundles it into the RN build — RN uses the @privy-io/expo provider instead.
4613
4578
  async function loadPrivyWalletProvider() {
4614
- const mod = await import('./privy-wallet-provider-D7VoQCYf.mjs');
4579
+ const mod = await import('./privy-wallet-provider-oG3o5vko.mjs');
4615
4580
  return mod.PrivyWalletProvider;
4616
4581
  }
4617
4582
  async function loadSolanaMobileWalletProvider() {
4618
- const mod = await import('./solana-mobile-wallet-provider-DgcGxDoL.mjs');
4583
+ const mod = await import('./solana-mobile-wallet-provider-aS60_GZR.mjs');
4619
4584
  return mod.SolanaMobileWalletProvider;
4620
4585
  }
4621
4586
  function requireWebPrivyConfig(config) {
@@ -4661,38 +4626,6 @@ function requireMobileWalletConfig(config) {
4661
4626
  }
4662
4627
  return Object.assign(Object.assign({}, ((_c = config.mobileWalletConfig) !== null && _c !== void 0 ? _c : {})), { cluster });
4663
4628
  }
4664
- function isLocalOrTestUrl(value) {
4665
- if (!value)
4666
- return false;
4667
- try {
4668
- const hostname = new URL(value).hostname.toLowerCase();
4669
- return hostname === 'localhost' ||
4670
- hostname === '127.0.0.1' ||
4671
- hostname === '::1' ||
4672
- hostname.endsWith('.localhost') ||
4673
- hostname.endsWith('.test');
4674
- }
4675
- catch (_a) {
4676
- return false;
4677
- }
4678
- }
4679
- function assertMockAuthLocalOnly(config) {
4680
- const requiredEndpoints = [
4681
- config.apiUrl,
4682
- config.wsApiUrl,
4683
- config.authApiUrl,
4684
- ];
4685
- const optionalEndpoints = [
4686
- config.rpcUrl,
4687
- config.humanAuthApiUrl,
4688
- config.functionsUrl,
4689
- ].filter((value) => typeof value === 'string' && value.trim() !== '');
4690
- if (requiredEndpoints.every(isLocalOrTestUrl) && optionalEndpoints.every(isLocalOrTestUrl)) {
4691
- return;
4692
- }
4693
- throw new Error("mockAuth is local/test-only. Pass explicit localhost/.test apiUrl, wsApiUrl, and authApiUrl values; " +
4694
- "mockAuth cannot be used with Bounded production or staging endpoints.");
4695
- }
4696
4629
  async function hotSwapToMWAProvider(config) {
4697
4630
  var _a;
4698
4631
  const rpcUrl = normalizeSolanaRpcUrl(config.rpcUrl);
@@ -4717,6 +4650,7 @@ async function hotSwapToMWAProvider(config) {
4717
4650
  }
4718
4651
  currentAuthProvider = provider;
4719
4652
  currentAuthMethod = 'mobile-wallet-adapter';
4653
+ currentAuthProviderConfigKey = authProviderConfigKey(Object.assign(Object.assign({}, config), { authMethod: 'mobile-wallet-adapter' }));
4720
4654
  const coreConfig = await getConfig();
4721
4655
  coreConfig.authProvider = provider;
4722
4656
  // Send 'phantom' as authMethod so the server routes to Solana verification.
@@ -4727,20 +4661,19 @@ async function hotSwapToMWAProvider(config) {
4727
4661
  }
4728
4662
  async function getAuthProvider(config) {
4729
4663
  var _a, _b;
4730
- if (currentAuthProvider) {
4664
+ const nextProviderConfigKey = config ? authProviderConfigKey(config) : null;
4665
+ if (currentAuthProvider && (!config || currentAuthProviderConfigKey === nextProviderConfigKey)) {
4731
4666
  return currentAuthProvider;
4732
4667
  }
4733
4668
  if (!config) {
4734
4669
  throw new Error("Config is required to initialize auth provider");
4735
4670
  }
4736
- initConfig = config;
4737
- // If mockAuth is enabled, use MockAuthProvider regardless of authMethod
4738
- if (config.mockAuth) {
4739
- assertMockAuthLocalOnly(config);
4740
- console.log("[MockAuth] Mock authentication enabled");
4741
- currentAuthProvider = new MockAuthProvider();
4742
- return currentAuthProvider;
4671
+ if (currentAuthProvider && currentAuthProviderConfigKey !== nextProviderConfigKey) {
4672
+ currentAuthProvider = null;
4673
+ currentAuthMethod = null;
4674
+ currentAuthProviderConfigKey = null;
4743
4675
  }
4676
+ initConfig = config;
4744
4677
  const authMethod = config.authMethod;
4745
4678
  if (!authMethod) {
4746
4679
  throw new Error("authMethod is required to initialize auth provider; configure the single intended auth method explicitly.");
@@ -4822,6 +4755,7 @@ async function getAuthProvider(config) {
4822
4755
  console.log("[Offchain] Wrapping auth provider for Poofnet transaction tracking");
4823
4756
  currentAuthProvider = new OffchainAuthProvider(currentAuthProvider);
4824
4757
  }
4758
+ currentAuthProviderConfigKey = nextProviderConfigKey;
4825
4759
  return currentAuthProvider;
4826
4760
  }
4827
4761
  /**
@@ -4851,6 +4785,7 @@ async function signInAnonymously() {
4851
4785
  const provider = new GuestAuthProvider();
4852
4786
  currentAuthProvider = provider;
4853
4787
  currentAuthMethod = 'guest';
4788
+ currentAuthProviderConfigKey = 'direct:guest';
4854
4789
  const coreConfig = await getConfig();
4855
4790
  coreConfig.authProvider = provider;
4856
4791
  coreConfig.authMethod = 'guest';
@@ -4895,6 +4830,7 @@ async function loginWithPrivy(options) {
4895
4830
  provider = new OffchainAuthProvider(provider);
4896
4831
  }
4897
4832
  currentAuthProvider = provider;
4833
+ currentAuthProviderConfigKey = authProviderConfigKey(Object.assign(Object.assign({}, coreConfig), { authMethod: currentAuthMethod }));
4898
4834
  coreConfig.authProvider = provider;
4899
4835
  coreConfig.authMethod = currentAuthMethod;
4900
4836
  setAuthProviderInstance(provider);
@@ -4911,6 +4847,7 @@ async function activateEmailProvider() {
4911
4847
  const provider = new EmailAuthProvider();
4912
4848
  currentAuthProvider = provider;
4913
4849
  currentAuthMethod = 'email';
4850
+ currentAuthProviderConfigKey = 'direct:email';
4914
4851
  const coreConfig = await getConfig();
4915
4852
  coreConfig.authProvider = provider;
4916
4853
  coreConfig.authMethod = 'email';
@@ -5037,6 +4974,7 @@ async function logout$1() {
5037
4974
  setStoredAuthMethod(null);
5038
4975
  currentAuthProvider = null;
5039
4976
  currentAuthMethod = null;
4977
+ currentAuthProviderConfigKey = null;
5040
4978
  }
5041
4979
 
5042
4980
  /**
@@ -5683,5 +5621,5 @@ class PrivyExpoProvider {
5683
5621
  }
5684
5622
  }
5685
5623
 
5686
- export { loginWithRedirect as A, linkWithRedirect as B, completeLoginFromRedirect as C, loginWithPopup as D, completeLoginInPopup as E, useAuth as F, deserializeTransaction as G, getIdToken as H, setPlatform as I, DEFAULT_TEST_ADDRESS as J, index as K, MockAuthProvider as M, OffchainAuthProvider as O, PrivyExpoProvider as P, SURFNET_RPC_URL as S, detectAndroid as a, bufferExports as b, confirmAndCheckTransaction as c, detectMobile as d, setAuthLoading as e, resolveSolanaWalletStandardChain as f, getPlatform as g, bs58 as h, init as i, getCurrentUser as j, onAuthLoadingChanged as k, getAuthLoading as l, login as m, normalizeSolanaRpcUrl as n, onAuthStateChanged as o, logout as p, getAuthProvider as q, resolveSolanaRpcUrl as r, setCurrentUser as s, signInAnonymously as t, sendEmailOtp as u, sendTextOtp as v, verifyEmailOtp as w, verifyTextOtp as x, linkEmail as y, loginWithPrivy as z };
5687
- //# sourceMappingURL=index.native-DWI_i6-6.mjs.map
5624
+ export { loginWithRedirect as A, linkWithRedirect as B, completeLoginFromRedirect as C, loginWithPopup as D, completeLoginInPopup as E, useAuth as F, deserializeTransaction as G, getIdToken as H, setPlatform as I, index as J, OffchainAuthProvider as O, PrivyExpoProvider as P, SURFNET_RPC_URL as S, detectAndroid as a, bufferExports as b, confirmAndCheckTransaction as c, detectMobile as d, setAuthLoading as e, resolveSolanaWalletStandardChain as f, getPlatform as g, bs58 as h, init as i, getCurrentUser as j, onAuthLoadingChanged as k, getAuthLoading as l, login as m, normalizeSolanaRpcUrl as n, onAuthStateChanged as o, logout as p, getAuthProvider as q, resolveSolanaRpcUrl as r, setCurrentUser as s, signInAnonymously as t, sendEmailOtp as u, sendTextOtp as v, verifyEmailOtp as w, verifyTextOtp as x, linkEmail as y, loginWithPrivy as z };
5625
+ //# sourceMappingURL=index.native-N3xLU862.mjs.map