@bounded-sh/client 0.0.110 → 0.0.112-ux-audit.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.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/dist/auth/index.d.ts +3 -1
  3. package/dist/auth/oidc-auth.d.ts +2 -0
  4. package/dist/auth/providers/email-auth-provider.d.ts +1 -1
  5. package/dist/auth/providers/guest-auth-provider.d.ts +1 -1
  6. package/dist/auth/providers/injected-evm-wallet-provider.d.ts +1 -1
  7. package/dist/auth/providers/injected-wallet-provider.d.ts +1 -1
  8. package/dist/auth/providers/offchain-auth-provider.d.ts +1 -1
  9. package/dist/auth/providers/privy-expo-provider.d.ts +1 -1
  10. package/dist/auth/solana-rpc.d.ts +9 -0
  11. package/dist/{email-auth-provider-D9SQu9c1.mjs → email-auth-provider-BfCH7K6N.mjs} +4 -3
  12. package/dist/email-auth-provider-BfCH7K6N.mjs.map +1 -0
  13. package/dist/{email-auth-provider-T-Go_9h9.js → email-auth-provider-CG5cxOj0.js} +4 -3
  14. package/dist/email-auth-provider-CG5cxOj0.js.map +1 -0
  15. package/dist/{email-auth-provider-Czo-xM6n.js → email-auth-provider-DTrCfOJd.js} +4 -3
  16. package/dist/email-auth-provider-DTrCfOJd.js.map +1 -0
  17. package/dist/{email-auth-provider-BPeQo6xL.mjs → email-auth-provider-eyi3Wpnx.mjs} +4 -3
  18. package/dist/email-auth-provider-eyi3Wpnx.mjs.map +1 -0
  19. package/dist/{guest-auth-provider-BIohNOHi.mjs → guest-auth-provider-BsW56oJg.mjs} +10 -5
  20. package/dist/guest-auth-provider-BsW56oJg.mjs.map +1 -0
  21. package/dist/{guest-auth-provider-DsFTB844.mjs → guest-auth-provider-DjOFjtnk.mjs} +10 -5
  22. package/dist/guest-auth-provider-DjOFjtnk.mjs.map +1 -0
  23. package/dist/{guest-auth-provider-BDhwvzem.js → guest-auth-provider-Dtl1J-2F.js} +10 -5
  24. package/dist/guest-auth-provider-Dtl1J-2F.js.map +1 -0
  25. package/dist/{guest-auth-provider-DJ5nCGjq.js → guest-auth-provider-Tndt6tzJ.js} +10 -5
  26. package/dist/guest-auth-provider-Tndt6tzJ.js.map +1 -0
  27. package/dist/{index-Cs5nPIzA.js → index-Brdwqgqs.js} +256 -67
  28. package/dist/index-Brdwqgqs.js.map +1 -0
  29. package/dist/{index-DbXoOlIa.mjs → index-CRxls8Qc.mjs} +257 -68
  30. package/dist/index-CRxls8Qc.mjs.map +1 -0
  31. package/dist/index.js +1 -1
  32. package/dist/index.mjs +1 -1
  33. package/dist/{index.native-BSOqaKIz.mjs → index.native-CAH_ks0s.mjs} +245 -63
  34. package/dist/index.native-CAH_ks0s.mjs.map +1 -0
  35. package/dist/{index.native-BpcNwWQX.js → index.native-ingNhWPw.js} +244 -62
  36. package/dist/index.native-ingNhWPw.js.map +1 -0
  37. package/dist/index.native.js +1 -1
  38. package/dist/index.native.mjs +1 -1
  39. package/dist/{injected-evm-wallet-provider-BjqqLfPD.mjs → injected-evm-wallet-provider-BjkCeRBL.mjs} +4 -3
  40. package/dist/injected-evm-wallet-provider-BjkCeRBL.mjs.map +1 -0
  41. package/dist/{injected-evm-wallet-provider-_UNpc_hM.js → injected-evm-wallet-provider-Cao1U0NZ.js} +4 -3
  42. package/dist/{injected-evm-wallet-provider-_UNpc_hM.js.map → injected-evm-wallet-provider-Cao1U0NZ.js.map} +1 -1
  43. package/dist/{injected-evm-wallet-provider-CMl0Fyxk.js → injected-evm-wallet-provider-CwOGXCDt.js} +4 -3
  44. package/dist/injected-evm-wallet-provider-CwOGXCDt.js.map +1 -0
  45. package/dist/{injected-evm-wallet-provider-Xb2G-ZGI.mjs → injected-evm-wallet-provider-DXjwPjLW.mjs} +4 -3
  46. package/dist/{injected-evm-wallet-provider-Xb2G-ZGI.mjs.map → injected-evm-wallet-provider-DXjwPjLW.mjs.map} +1 -1
  47. package/dist/{injected-wallet-provider-D-Pq9QVK.mjs → injected-wallet-provider-BG6gGNch.mjs} +4 -3
  48. package/dist/{injected-wallet-provider-D-Pq9QVK.mjs.map → injected-wallet-provider-BG6gGNch.mjs.map} +1 -1
  49. package/dist/{injected-wallet-provider-DZOwvKgd.mjs → injected-wallet-provider-CfYNIIHd.mjs} +4 -3
  50. package/dist/{injected-wallet-provider-DZOwvKgd.mjs.map → injected-wallet-provider-CfYNIIHd.mjs.map} +1 -1
  51. package/dist/{injected-wallet-provider-C7Q0haGY.js → injected-wallet-provider-DSlHfgMU.js} +4 -3
  52. package/dist/{injected-wallet-provider-C7Q0haGY.js.map → injected-wallet-provider-DSlHfgMU.js.map} +1 -1
  53. package/dist/{injected-wallet-provider-CgHOrtmj.js → injected-wallet-provider-LTnqoaYD.js} +4 -3
  54. package/dist/{injected-wallet-provider-CgHOrtmj.js.map → injected-wallet-provider-LTnqoaYD.js.map} +1 -1
  55. package/package.json +2 -2
  56. package/dist/email-auth-provider-BPeQo6xL.mjs.map +0 -1
  57. package/dist/email-auth-provider-Czo-xM6n.js.map +0 -1
  58. package/dist/email-auth-provider-D9SQu9c1.mjs.map +0 -1
  59. package/dist/email-auth-provider-T-Go_9h9.js.map +0 -1
  60. package/dist/guest-auth-provider-BDhwvzem.js.map +0 -1
  61. package/dist/guest-auth-provider-BIohNOHi.mjs.map +0 -1
  62. package/dist/guest-auth-provider-DJ5nCGjq.js.map +0 -1
  63. package/dist/guest-auth-provider-DsFTB844.mjs.map +0 -1
  64. package/dist/index-Cs5nPIzA.js.map +0 -1
  65. package/dist/index-DbXoOlIa.mjs.map +0 -1
  66. package/dist/index.native-BSOqaKIz.mjs.map +0 -1
  67. package/dist/index.native-BpcNwWQX.js.map +0 -1
  68. package/dist/injected-evm-wallet-provider-BjqqLfPD.mjs.map +0 -1
  69. package/dist/injected-evm-wallet-provider-CMl0Fyxk.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Cs5nPIzA.js');
3
+ var index = require('./index-Brdwqgqs.js');
4
4
  var core = require('@bounded-sh/core');
5
5
  require('react');
6
6
 
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { ag as BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA, af as BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA, ae as BUILD_REVIEW_CAPABILITY_SCHEMA, a7 as BuildsApiError, ad as FAILURE_REASONS, a9 as NON_TERMINAL_STATES, a1 as OffchainAuthProvider, ac as PARK_REASONS, a2 as PrivyExpoProvider, ab as RUN_STATES, aa as TERMINAL_STATES, W as WalletConfigError, Q as apps, a6 as builds, I as completeLoginFromRedirect, a4 as connectBroadcast, a5 as connectServiceSession, o as defaultInjectedEvmProvider, f as defaultInjectedProvider, F as ensureSharedWalletLoginReady, M as ensureSignedIn, E as ensureWalletLoginReady, w as getAuthLoading, A as getAuthProvider, q as getCurrentUser, Y as getIdToken, J as getLoginReturnError, S as getOrCreateTurnkeyWallet, g as getPlatform, V as getTurnkeyWalletRecoveryUrl, U as getTurnkeyWalletSessionState, p as init, y as login, K as loginWithPopup, C as loginWithPrivy, H as loginWithRedirect, D as loginWithWallet, z as logout, a8 as mediaAgentTools, v as onAuthLoadingChanged, u as onAuthStateChanged, Z as onramp, _ as onrampQuote, $ as onrampStatus, L as openBoundedWidget, T as openTurnkeyKeyExport, G as preloadWalletLogin, a3 as requestEip6963Providers, a0 as setPlatform, B as signInAnonymously, R as signSolanaMessageViaTurnkey, X as startTurnkeyEmailLogin, N as useAuth, P as useBuildRun, O as useQuery, x as waitForAuthReady } from './index-DbXoOlIa.mjs';
1
+ export { ag as BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA, af as BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA, ae as BUILD_REVIEW_CAPABILITY_SCHEMA, a7 as BuildsApiError, ad as FAILURE_REASONS, a9 as NON_TERMINAL_STATES, a1 as OffchainAuthProvider, ac as PARK_REASONS, a2 as PrivyExpoProvider, ab as RUN_STATES, aa as TERMINAL_STATES, W as WalletConfigError, Q as apps, a6 as builds, I as completeLoginFromRedirect, a4 as connectBroadcast, a5 as connectServiceSession, o as defaultInjectedEvmProvider, f as defaultInjectedProvider, F as ensureSharedWalletLoginReady, M as ensureSignedIn, E as ensureWalletLoginReady, w as getAuthLoading, A as getAuthProvider, q as getCurrentUser, Y as getIdToken, J as getLoginReturnError, S as getOrCreateTurnkeyWallet, g as getPlatform, V as getTurnkeyWalletRecoveryUrl, U as getTurnkeyWalletSessionState, p as init, y as login, K as loginWithPopup, C as loginWithPrivy, H as loginWithRedirect, D as loginWithWallet, z as logout, a8 as mediaAgentTools, v as onAuthLoadingChanged, u as onAuthStateChanged, Z as onramp, _ as onrampQuote, $ as onrampStatus, L as openBoundedWidget, T as openTurnkeyKeyExport, G as preloadWalletLogin, a3 as requestEip6963Providers, a0 as setPlatform, B as signInAnonymously, R as signSolanaMessageViaTurnkey, X as startTurnkeyEmailLogin, N as useAuth, P as useBuildRun, O as useQuery, x as waitForAuthReady } from './index-CRxls8Qc.mjs';
2
2
  export * from '@bounded-sh/core';
3
3
  export { AppTokenExchangeError, BoundedDeclineError, DECLINE_EVENT_NAME, RATE_LIMIT_EVENT_NAME, ScopedClientReadOnlyError, aggregate, clearAppTokenCache, count, createAppTokenAuthHeaders, createClient, deriveDecline, dispatchDeclineEvent, dispatchRateLimitEvent, docId, exchangeAppToken, get, getConfig, getFiles, getMany, queryAggregate, reconcileSetResult, runExpression, runExpressionMany, runQuery, runQueryMany, search, set, setFile, setMany, signAndSubmitTransaction, signMessage, signTransaction, subscribe, waitForSetResult } from '@bounded-sh/core';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { getConfig, getActiveSessionManager, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, reconnectWithNewAuth, onSessionCleared, deriveUserIdentityFromIdToken, subscribe, getFreshAuthToken, getSessionGeneration, getIdToken as getIdToken$1, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
1
+ import { getConfig, getActiveSessionManager, WebSessionManager, ReactNativeSessionManager, revokeSession, reconnectWithNewAuth, init as init$1, deriveUserIdentityFromIdToken, onSessionCleared, subscribe, getFreshAuthToken, getSessionGeneration, getIdToken as getIdToken$1, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
2
2
  import * as React from 'react';
3
3
 
4
4
  function walletContextFromClaims(claims, baseUrl, expectedAppId, tenantOrigin) {
@@ -215,8 +215,9 @@ class OffchainAuthProvider {
215
215
  async logout() {
216
216
  await this.wrappedProvider.logout();
217
217
  }
218
- async restoreSession() {
219
- const user = await this.wrappedProvider.restoreSession();
218
+ async restoreSession(beforeCommit) {
219
+ const provider = this.wrappedProvider;
220
+ const user = await provider.restoreSession(beforeCommit);
220
221
  if (user) {
221
222
  return Object.assign(Object.assign({}, user), { provider: this });
222
223
  }
@@ -686,6 +687,8 @@ async function clearSessionProviderForLogout() {
686
687
  setStoredAuthMethod(null);
687
688
  }
688
689
 
690
+ const SOLANA_DEVNET_RPC_URL = "https://idelle-8nxsep-fast-devnet.helius-rpc.com";
691
+ const SOLANA_MAINNET_RPC_URL = "https://celestia-cegncv-fast-mainnet.helius-rpc.com";
689
692
  const SUPPORTED_SOLANA_NETWORKS = new Set([
690
693
  "solana_devnet",
691
694
  "solana_mainnet",
@@ -715,15 +718,35 @@ function resolveSolanaWalletStandardChain(network, context) {
715
718
  `Expected one of: solana_devnet, solana_mainnet.`);
716
719
  }
717
720
  }
721
+ /**
722
+ * The platform RPC endpoint for a supported Solana network, or null when the
723
+ * network is missing or unsupported. Used when the app passes no rpcUrl.
724
+ */
725
+ function defaultSolanaRpcUrl(network) {
726
+ switch (network) {
727
+ case "solana_mainnet":
728
+ return SOLANA_MAINNET_RPC_URL;
729
+ case "solana_devnet":
730
+ return SOLANA_DEVNET_RPC_URL;
731
+ default:
732
+ return null;
733
+ }
734
+ }
735
+ /**
736
+ * An explicit rpcUrl always wins. Otherwise the platform RPC for the configured
737
+ * network is used. With neither, fail closed.
738
+ */
718
739
  function resolveSolanaRpcUrl(explicitRpcUrl, network, context) {
740
+ var _a;
719
741
  if (network != null && network !== "" && !isSupportedSolanaRpcNetwork(network)) {
720
742
  throw new Error(`${context} does not support Solana network "${network}". ` +
721
743
  `Expected one of: solana_devnet, solana_mainnet.`);
722
744
  }
723
- const rpcUrl = normalizeSolanaRpcUrl(explicitRpcUrl);
745
+ const rpcUrl = (_a = normalizeSolanaRpcUrl(explicitRpcUrl)) !== null && _a !== void 0 ? _a : defaultSolanaRpcUrl(network);
724
746
  if (rpcUrl)
725
747
  return rpcUrl;
726
- throw new Error(`${context} requires an explicit Solana RPC URL. Pass config.rpcUrl before signing or submitting onchain transactions.`);
748
+ throw new Error(`${context} requires a Solana network. Set init({ chain: "solana_mainnet" | "solana_devnet" }) ` +
749
+ `or pass config.rpcUrl before signing or submitting onchain transactions.`);
727
750
  }
728
751
 
729
752
  var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
@@ -5254,7 +5277,8 @@ async function loginWithRedirect(opts) {
5254
5277
  return runNativeLogin(opts);
5255
5278
  if (!hasDOM$1())
5256
5279
  throw new Error('loginWithRedirect requires a browser or a configured React Native platform');
5257
- const { url, pkce } = await buildAuthorize(opts);
5280
+ const { url, pkce } = await untilAborted(buildAuthorize(opts), opts.signal);
5281
+ throwIfCancelled(opts.signal);
5258
5282
  // Stash the verifier + state so the redirect_uri page can finish the exchange. sessionStorage
5259
5283
  // is per-tab and cleared on close — appropriate for a short-lived auth handshake. Keyed by
5260
5284
  // this attempt's own state so a second concurrent login cannot overwrite it.
@@ -5283,9 +5307,29 @@ async function completeLoginFromRedirect() {
5283
5307
  throw error;
5284
5308
  return result.user;
5285
5309
  }
5310
+ function throwIfCancelled(signal) {
5311
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
5312
+ throw new Error('cancelled');
5313
+ }
5314
+ async function untilAborted(work, signal) {
5315
+ if (!signal)
5316
+ return work;
5317
+ throwIfCancelled(signal);
5318
+ let onAbort;
5319
+ try {
5320
+ return await Promise.race([work, new Promise((_, reject) => {
5321
+ onAbort = () => reject(new Error('cancelled'));
5322
+ signal.addEventListener('abort', onAbort, { once: true });
5323
+ })]);
5324
+ }
5325
+ finally {
5326
+ signal.removeEventListener('abort', onAbort);
5327
+ }
5328
+ }
5286
5329
  /** Popup variant: open the hosted login in a popup; resolves with the User once the popup's
5287
5330
  * redirect_uri page initializes the SDK, which hands the code back automatically. */
5288
5331
  async function loginWithPopup(opts) {
5332
+ throwIfCancelled(opts.signal);
5289
5333
  if (!hasDOM$1())
5290
5334
  throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
5291
5335
  // Open synchronously, before PKCE/config awaits consume the click's user-
@@ -5303,7 +5347,7 @@ async function loginWithPopup(opts) {
5303
5347
  throw new Error('Popup blocked — use loginWithRedirect() instead');
5304
5348
  let authorization;
5305
5349
  try {
5306
- authorization = await buildAuthorize(opts, 'popup');
5350
+ authorization = await untilAborted(buildAuthorize(opts, 'popup'), opts.signal);
5307
5351
  }
5308
5352
  catch (error) {
5309
5353
  try {
@@ -5320,6 +5364,7 @@ async function loginWithPopup(opts) {
5320
5364
  // window with no listener or watchdog attached.
5321
5365
  let expectedOrigin;
5322
5366
  try {
5367
+ throwIfCancelled(opts.signal);
5323
5368
  expectedOrigin = new URL(pkce.redirectUri).origin;
5324
5369
  sessionStorage.setItem(pkceKey(pkce.state), JSON.stringify(pkce));
5325
5370
  }
@@ -5351,20 +5396,42 @@ async function loginWithPopup(opts) {
5351
5396
  setAuthLoading(true); // reflect "signing in…" while the popup is open
5352
5397
  try {
5353
5398
  return await new Promise((resolve, reject) => {
5399
+ var _a, _b;
5354
5400
  let settled = false;
5401
+ let handedOff = false;
5402
+ let committing = false;
5355
5403
  let timer;
5356
5404
  let navigationTimer;
5357
5405
  let completionTimer;
5358
5406
  const cleanup = () => {
5359
- settled = true;
5360
5407
  clearInterval(timer);
5361
5408
  clearTimeout(navigationTimer);
5362
5409
  clearTimeout(completionTimer);
5363
5410
  window.removeEventListener('message', onMsg);
5364
5411
  removeAttempt(pkce.state);
5365
5412
  };
5413
+ const finish = (error, user) => {
5414
+ var _a;
5415
+ if (settled)
5416
+ return;
5417
+ settled = true;
5418
+ cleanup();
5419
+ (_a = opts.signal) === null || _a === void 0 ? void 0 : _a.removeEventListener('abort', onAbort);
5420
+ try {
5421
+ popup.close();
5422
+ }
5423
+ catch ( /* ignore */_b) { /* ignore */ }
5424
+ if (error)
5425
+ reject(error);
5426
+ else
5427
+ resolve(user);
5428
+ };
5429
+ // Provider adoption commits synchronously after its final guard. An auth
5430
+ // listener dismissing the card there cannot cancel an already signed-in user.
5431
+ const onAbort = () => { if (!committing)
5432
+ finish(new Error('cancelled')); };
5366
5433
  const onMsg = async (ev) => {
5367
- if (settled || ev.origin !== expectedOrigin || ev.source !== popup)
5434
+ if (settled || handedOff || ev.origin !== expectedOrigin || ev.source !== popup)
5368
5435
  return;
5369
5436
  const d = ev.data;
5370
5437
  if (!d || d.type !== 'bounded-oidc-code' ||
@@ -5378,35 +5445,30 @@ async function loginWithPopup(opts) {
5378
5445
  return;
5379
5446
  if (d.appId !== pkce.appId || d.issuer !== pkce.issuer)
5380
5447
  return;
5448
+ handedOff = true;
5381
5449
  cleanup();
5382
5450
  try {
5451
+ throwIfCancelled(opts.signal);
5383
5452
  await validateAttempt(pkce, new URL(d.callbackUrl));
5453
+ throwIfCancelled(opts.signal);
5384
5454
  popup.postMessage({ type: 'bounded-oidc-accepted', state: pkce.state }, expectedOrigin);
5385
5455
  if (d.error)
5386
5456
  throw new Error(typeof d.errorDescription === 'string' ? d.errorDescription : `Login failed: ${d.error}`);
5387
- const user = await exchangeCode(d.code, pkce);
5388
- try {
5389
- popup.close();
5390
- }
5391
- catch ( /* ignore */_a) { /* ignore */ }
5392
- resolve(user);
5457
+ const user = await exchangeCode(d.code, pkce, opts.signal, () => { committing = true; });
5458
+ finish(undefined, user);
5393
5459
  }
5394
5460
  catch (e) {
5395
- try {
5396
- popup.close();
5397
- }
5398
- catch ( /* ignore */_b) { /* ignore */ }
5399
- reject(e);
5461
+ finish(e);
5400
5462
  }
5401
5463
  };
5464
+ (_a = opts.signal) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', onAbort, { once: true });
5465
+ if ((_b = opts.signal) === null || _b === void 0 ? void 0 : _b.aborted) {
5466
+ onAbort();
5467
+ return;
5468
+ }
5402
5469
  window.addEventListener('message', onMsg);
5403
5470
  completionTimer = setTimeout(() => {
5404
- cleanup();
5405
- try {
5406
- popup.close();
5407
- }
5408
- catch ( /* ignore */_a) { /* ignore */ }
5409
- reject(new Error('Login expired or its popup disconnected. Start sign-in again.'));
5471
+ finish(new Error('Login expired or its popup disconnected. Start sign-in again.'));
5410
5472
  }, LOGIN_TIMEOUT_MS);
5411
5473
  // Some browser/extension combinations can return a real popup handle but
5412
5474
  // strand the window at about:blank instead of navigating to the hosted
@@ -5427,23 +5489,18 @@ async function loginWithPopup(opts) {
5427
5489
  const NAVIGATION_RECHECK_MS = 2000;
5428
5490
  const navigationStartedAt = Date.now();
5429
5491
  const checkNavigation = () => {
5430
- if (settled || popup.closed)
5492
+ if (settled || handedOff || popup.closed)
5431
5493
  return;
5432
5494
  try {
5433
5495
  if (popup.location.href === 'about:blank') {
5434
5496
  if (Date.now() - navigationStartedAt >= NAVIGATION_GRACE_MS) {
5435
- cleanup();
5436
- try {
5437
- popup.close();
5438
- }
5439
- catch ( /* ignore */_a) { /* ignore */ }
5440
- reject(new Error('Popup stalled at about:blank - use loginWithRedirect() instead'));
5497
+ finish(new Error('Popup stalled at about:blank - use loginWithRedirect() instead'));
5441
5498
  return;
5442
5499
  }
5443
5500
  navigationTimer = setTimeout(checkNavigation, NAVIGATION_RECHECK_MS);
5444
5501
  }
5445
5502
  }
5446
- catch ( /* cross-origin hosted auth loaded normally */_b) { /* cross-origin hosted auth loaded normally */ }
5503
+ catch ( /* cross-origin hosted auth loaded normally */_a) { /* cross-origin hosted auth loaded normally */ }
5447
5504
  };
5448
5505
  navigationTimer = setTimeout(checkNavigation, NAVIGATION_RECHECK_MS);
5449
5506
  // The popup posts its code and then closes ITSELF, so a naive "popup.closed -> reject"
@@ -5453,10 +5510,8 @@ async function loginWithPopup(opts) {
5453
5510
  timer = setInterval(() => {
5454
5511
  if (popup.closed) {
5455
5512
  clearInterval(timer);
5456
- setTimeout(() => { if (!settled) {
5457
- cleanup();
5458
- reject(new Error('Login window closed'));
5459
- } }, 500);
5513
+ setTimeout(() => { if (!settled && !handedOff)
5514
+ finish(new Error('Login window closed')); }, 500);
5460
5515
  }
5461
5516
  }, 500);
5462
5517
  });
@@ -5465,9 +5520,10 @@ async function loginWithPopup(opts) {
5465
5520
  setAuthLoading(false);
5466
5521
  }
5467
5522
  }
5468
- async function exchangeCode(code, pkce) {
5523
+ async function exchangeCode(code, pkce, signal, onCommitting) {
5469
5524
  const generation = getInitializationGeneration();
5470
5525
  const beforeCommit = () => {
5526
+ throwIfCancelled(signal);
5471
5527
  if (generation !== getInitializationGeneration())
5472
5528
  throw new Error('Login was superseded by SDK reinitialization. Start sign-in again.');
5473
5529
  };
@@ -5483,7 +5539,7 @@ async function exchangeCode(code, pkce) {
5483
5539
  let res;
5484
5540
  try {
5485
5541
  res = await fetch(`${base}/api/auth/oauth2/token`, {
5486
- method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString(),
5542
+ method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString(), signal,
5487
5543
  });
5488
5544
  }
5489
5545
  catch (err) {
@@ -5509,7 +5565,7 @@ async function exchangeCode(code, pkce) {
5509
5565
  // Adopt on EVERY session surface (see establishInlineSession) - hosted
5510
5566
  // popup/redirect completions all land here, so this closes their gap too.
5511
5567
  try {
5512
- await adoptSessionProvider({ provider: oidcProviderSingleton, method: 'email', configKey: 'direct:oidc', user, beforeCommit });
5568
+ await adoptSessionProvider({ provider: oidcProviderSingleton, method: 'email', configKey: 'direct:oidc', user, beforeCommit: () => { beforeCommit(); onCommitting === null || onCommitting === void 0 ? void 0 : onCommitting(); } });
5513
5569
  }
5514
5570
  catch (error) {
5515
5571
  if (typeof rollback === 'function')
@@ -5578,6 +5634,31 @@ function idTokenIsGuest(idToken, expectedAddress) {
5578
5634
  function storedSessionIsGuest() {
5579
5635
  return idTokenIsGuest(getStoredIdToken());
5580
5636
  }
5637
+ /** Internal: select a cross-tab restore from bearer claims, never global hints. */
5638
+ function storedSessionAuthMethod(config) {
5639
+ try {
5640
+ const token = getStoredIdToken();
5641
+ if (!token)
5642
+ return null;
5643
+ let payload = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
5644
+ payload += '='.repeat((4 - payload.length % 4) % 4);
5645
+ const claims = JSON.parse(getPlatform().atob(payload));
5646
+ const method = claims.is_anonymous === true ? 'guest'
5647
+ : claims['custom:walletProvider'] === 'turnkey' || claims.email ? 'email'
5648
+ : claims['custom:evmWalletAddress'] ? 'evm-wallet'
5649
+ : claims['custom:walletAddress'] ? 'phantom' : 'email';
5650
+ if (config.authMethod != null && canonicalWalletAuthMethod(config.authMethod) !== method)
5651
+ return null;
5652
+ if (method === 'evm-wallet' && config.authMethod !== 'evm-wallet')
5653
+ return null;
5654
+ if (method === 'phantom' && (isWalletLoginDisabled(config) || isEmailRequired(config)))
5655
+ return null;
5656
+ return method;
5657
+ }
5658
+ catch (_a) {
5659
+ return null;
5660
+ }
5661
+ }
5581
5662
  /**
5582
5663
  * Pick the provider used for an ordinary `init({ appId })` restore.
5583
5664
  *
@@ -5824,9 +5905,10 @@ function optionalProviderError(method) {
5824
5905
  `loginWithRedirect(...) for Bounded Auth, signInAnonymously() for guests, ` +
5825
5906
  `or install/import an explicit wallet-provider entry once your app opts into "${method}".`);
5826
5907
  }
5827
- async function getAuthProvider(config) {
5908
+ async function getAuthProvider(config, fromStorage = false) {
5828
5909
  var _a;
5829
- const nextProviderConfigKey = config ? authProviderConfigKey(config) : null;
5910
+ const requestedAuthMethod = config ? (fromStorage ? storedSessionAuthMethod(config) : authMethodForInit(config)) : null;
5911
+ const nextProviderConfigKey = config ? authProviderConfigKey(Object.assign(Object.assign({}, config), { authMethod: requestedAuthMethod })) : null;
5830
5912
  if (currentAuthProvider && (!config || currentAuthProviderConfigKey === nextProviderConfigKey)) {
5831
5913
  return currentAuthProvider;
5832
5914
  }
@@ -5841,7 +5923,8 @@ async function getAuthProvider(config) {
5841
5923
  initConfig = config;
5842
5924
  // Keep what the app actually wrote for error text; everything else runs on
5843
5925
  // the canonical method so exactly one string reaches storage and the issuer.
5844
- const requestedAuthMethod = authMethodForInit(config);
5926
+ if (!requestedAuthMethod)
5927
+ throw new Error('The stored session is incompatible with this app authentication configuration.');
5845
5928
  const authMethod = canonicalWalletAuthMethod(requestedAuthMethod);
5846
5929
  const rpcUrl = normalizeSolanaRpcUrl(config.rpcUrl);
5847
5930
  const configuredNetwork = getConfiguredSolanaNetwork(config);
@@ -5866,7 +5949,7 @@ async function getAuthProvider(config) {
5866
5949
  // manager as legacy email sessions. Human login should be started
5867
5950
  // with loginWithRedirect(); this provider is kept as the restore and
5868
5951
  // logout surface for those sessions.
5869
- currentAuthProvider = new (await import('./email-auth-provider-D9SQu9c1.mjs')).EmailAuthProvider();
5952
+ currentAuthProvider = new (await import('./email-auth-provider-BfCH7K6N.mjs')).EmailAuthProvider();
5870
5953
  break;
5871
5954
  case "phantom": {
5872
5955
  // First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
@@ -5908,7 +5991,7 @@ async function getAuthProvider(config) {
5908
5991
  // (bounded-login-widget.ts), so registration never counts as
5909
5992
  // evidence the user has a wallet.
5910
5993
  await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
5911
- const { InjectedWalletProvider } = await import('./injected-wallet-provider-DZOwvKgd.mjs');
5994
+ const { InjectedWalletProvider } = await import('./injected-wallet-provider-CfYNIIHd.mjs');
5912
5995
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
5913
5996
  break;
5914
5997
  }
@@ -5921,7 +6004,7 @@ async function getAuthProvider(config) {
5921
6004
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
5922
6005
  // to point at a specific wallet or set chainId/domain.
5923
6006
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
5924
- const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-Xb2G-ZGI.mjs');
6007
+ const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-DXjwPjLW.mjs');
5925
6008
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
5926
6009
  break;
5927
6010
  }
@@ -5946,7 +6029,7 @@ async function getAuthProvider(config) {
5946
6029
  break;
5947
6030
  case "guest":
5948
6031
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
5949
- currentAuthProvider = new (await import('./guest-auth-provider-DsFTB844.mjs')).GuestAuthProvider();
6032
+ currentAuthProvider = new (await import('./guest-auth-provider-DjOFjtnk.mjs')).GuestAuthProvider();
5950
6033
  break;
5951
6034
  }
5952
6035
  if (!currentAuthProvider) {
@@ -6008,7 +6091,7 @@ async function signInAnonymously() {
6008
6091
  // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
6009
6092
  // the main bundle for data-only apps. Specifier is a static string literal
6010
6093
  // so bundle-splitting can see it.
6011
- const provider = new (await import('./guest-auth-provider-DsFTB844.mjs')).GuestAuthProvider();
6094
+ const provider = new (await import('./guest-auth-provider-DjOFjtnk.mjs')).GuestAuthProvider();
6012
6095
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
6013
6096
  // adoptSessionProvider awaits only getConfig() (already resolved here) and then
6014
6097
  // runs every write - provider/method/config/marker/user - in one synchronous
@@ -6179,7 +6262,7 @@ function ensureSharedWalletLoginReady() {
6179
6262
  if (!sharedWalletReady) {
6180
6263
  sharedWalletReady = (async () => {
6181
6264
  await getConfig();
6182
- await import('./injected-wallet-provider-DZOwvKgd.mjs');
6265
+ await import('./injected-wallet-provider-CfYNIIHd.mjs');
6183
6266
  })().catch((error) => {
6184
6267
  sharedWalletReady = null;
6185
6268
  throw error;
@@ -6400,6 +6483,17 @@ async function logout$1(options) {
6400
6483
  }
6401
6484
  }
6402
6485
 
6486
+ /**
6487
+ * An explicit rpcUrl wins; otherwise a Solana chain gets the platform RPC so
6488
+ * every onchain path (wallet signing, submission, reconcile) has one.
6489
+ */
6490
+ function withDefaultSolanaRpcUrl(config) {
6491
+ var _a;
6492
+ if (normalizeSolanaRpcUrl(config.rpcUrl))
6493
+ return config;
6494
+ const rpcUrl = defaultSolanaRpcUrl((_a = config.chain) === null || _a === void 0 ? void 0 : _a.trim());
6495
+ return rpcUrl ? Object.assign(Object.assign({}, config), { rpcUrl }) : config;
6496
+ }
6403
6497
  /**
6404
6498
  * Subscribed once per process, not per init(): re-registering on every init would
6405
6499
  * stack duplicate handlers on repeated initialization.
@@ -6464,11 +6558,80 @@ let isAuthLoading = false;
6464
6558
  let authReadyPromise = null;
6465
6559
  let initializingConfig = null;
6466
6560
  let initializationGeneration = 0;
6561
+ let initializedConfig = null;
6562
+ let storageBridgeRegistered = false;
6563
+ let observedIdToken = null;
6564
+ let observedIssuer = null;
6565
+ // Storage events carry no authority. Re-read the active manager's app/issuer
6566
+ // namespace, then use the ordinary initializer/provider restore and listeners.
6567
+ function registerStorageBridge() {
6568
+ if (storageBridgeRegistered || !getPlatform().hasDOM || typeof window === 'undefined')
6569
+ return;
6570
+ storageBridgeRegistered = true;
6571
+ window.addEventListener('storage', (event) => {
6572
+ if (event.storageArea !== window.localStorage || !initializedConfig)
6573
+ return;
6574
+ void syncStoredSession().catch((error) => console.warn('Bounded session synchronization failed:', error));
6575
+ });
6576
+ }
6577
+ async function syncStoredSession() {
6578
+ const config = initializedConfig;
6579
+ if (!config)
6580
+ return;
6581
+ const token = WebSessionManager.getIdToken();
6582
+ const issuer = WebSessionManager.getIssuer();
6583
+ if (token === observedIdToken && issuer === observedIssuer)
6584
+ return;
6585
+ observedIdToken = token;
6586
+ observedIssuer = issuer;
6587
+ const generation = ++initializationGeneration;
6588
+ // Hide the former principal while the replacement is validated. This also
6589
+ // reconnects live reads through the existing auth-state change path.
6590
+ setCurrentUser(null);
6591
+ if (authReadyPromise)
6592
+ await authReadyPromise.catch(() => { });
6593
+ if (generation !== initializationGeneration || config !== initializedConfig)
6594
+ return;
6595
+ const record = await WebSessionManager.readSessionWithGeneration();
6596
+ if (generation !== initializationGeneration || config !== initializedConfig)
6597
+ return;
6598
+ if (!record)
6599
+ return;
6600
+ const normalize = (url) => (url || '').replace(/\/+$/, '');
6601
+ const resolvedConfig = await getConfig();
6602
+ if (generation !== initializationGeneration || config !== initializedConfig)
6603
+ return;
6604
+ const allowedIssuers = [normalize(resolvedConfig.humanAuthApiUrl || 'https://auth.bounded.sh'), normalize(resolvedConfig.authApiUrl)].filter(Boolean);
6605
+ // A legacy shared blob can belong to another app. Never restore or clear
6606
+ // that app's credential; the current app remains signed out.
6607
+ if ((record.appId && record.appId !== config.appId)
6608
+ || (record.issuer && !allowedIssuers.includes(normalize(record.issuer))))
6609
+ return;
6610
+ if (!storedSessionAuthMethod(config))
6611
+ return;
6612
+ const restored = startInitialization(config, true);
6613
+ const restoreGeneration = initializationGeneration;
6614
+ try {
6615
+ await restored;
6616
+ }
6617
+ catch (error) {
6618
+ if (restoreGeneration === initializationGeneration && WebSessionManager.getIdToken())
6619
+ throw error;
6620
+ }
6621
+ }
6467
6622
  /** Internal guard for a login result arriving after the app reconfigured the SDK. */
6468
6623
  function getInitializationGeneration() { return initializationGeneration; }
6469
6624
  // This file acts as a middleware for the global state of the SDK
6470
6625
  // This mostly involves setting up the AuthProvider and managing the current user
6471
- async function initialize(newConfig) {
6626
+ async function initialize(requestedConfig, fromStorage) {
6627
+ const newConfig = withDefaultSolanaRpcUrl(requestedConfig);
6628
+ const generation = initializationGeneration;
6629
+ const validateStorage = fromStorage ? WebSessionManager.captureSessionEstablishment() : undefined;
6630
+ const beforeCommit = () => {
6631
+ if (generation !== initializationGeneration)
6632
+ throw new Error('Session restore was superseded.');
6633
+ validateStorage === null || validateStorage === void 0 ? void 0 : validateStorage();
6634
+ };
6472
6635
  // Mark auth as loading for the ENTIRE init/restore window so consumers render
6473
6636
  // a neutral/loading state instead of the signed-out UI while we rehydrate the
6474
6637
  // session — otherwise getCurrentUser() is null + loading is false during the
@@ -6487,8 +6650,9 @@ async function initialize(newConfig) {
6487
6650
  // onAuthStateChanged never fired, and every consumer UI went on showing a
6488
6651
  // connected wallet for a session the server no longer knew about.
6489
6652
  registerSessionClearedBridge();
6653
+ registerStorageBridge();
6490
6654
  // Get auth provider first
6491
- authProviderInstance = await getAuthProvider(newConfig);
6655
+ authProviderInstance = await getAuthProvider(newConfig, fromStorage);
6492
6656
  // Initialize config with auth provider
6493
6657
  await init$1(Object.assign(Object.assign({}, newConfig), { authProvider: authProviderInstance }));
6494
6658
  // A return establishes its own provider/session, or hands off a popup.
@@ -6513,7 +6677,8 @@ async function initialize(newConfig) {
6513
6677
  // Wait for restoreSession to complete
6514
6678
  // The appId check is done in SessionManager.getSession which is called by restoreSession
6515
6679
  // If there's an appId mismatch, the session will be cleared and restoreSession will return null
6516
- let user = await authProviderInstance.restoreSession();
6680
+ let user = await authProviderInstance.restoreSession(beforeCommit);
6681
+ beforeCommit();
6517
6682
  // If a session exists but was created before auth method tracking (legacy session),
6518
6683
  // clear it to avoid mismatches when the app switches auth methods (e.g. email → phantom)
6519
6684
  //
@@ -6521,9 +6686,10 @@ async function initialize(newConfig) {
6521
6686
  // unawaited call would return a Promise (always truthy) — nulling the user
6522
6687
  // unconditionally AND letting setCurrentUser run while the old credential
6523
6688
  // was still in storage.
6524
- if (user && await clearIncompatibleSession()) {
6689
+ if (user && !fromStorage && await clearIncompatibleSession()) {
6525
6690
  user = null;
6526
6691
  }
6692
+ beforeCommit();
6527
6693
  setCurrentUser(user);
6528
6694
  // Mark init as completed
6529
6695
  initCompleted = true;
@@ -6563,13 +6729,17 @@ function sameConfigValue(a, b, seen = new WeakMap()) {
6563
6729
  && sameConfigValue(a[key], b[key], seen));
6564
6730
  }
6565
6731
  function init(newConfig) {
6732
+ return startInitialization(newConfig, false);
6733
+ }
6734
+ function startInitialization(newConfig, fromStorage) {
6566
6735
  if (initializingConfig) {
6567
6736
  if (sameConfigValue(initializingConfig, newConfig)) {
6568
6737
  return authReadyPromise;
6569
6738
  }
6570
6739
  return Promise.reject(new Error('SDK initialization is in progress. Await init() before changing its configuration.'));
6571
6740
  }
6572
- initializingConfig = Object.assign({}, newConfig);
6741
+ initializedConfig = Object.assign({}, newConfig);
6742
+ initializingConfig = initializedConfig;
6573
6743
  initializationGeneration++;
6574
6744
  let resolveReady;
6575
6745
  let rejectReady;
@@ -6581,7 +6751,7 @@ function init(newConfig) {
6581
6751
  // auth-loading listener to call waitForAuthReady() synchronously when init()
6582
6752
  // announces that session restoration has begun.
6583
6753
  authReadyPromise = ready;
6584
- void initialize(initializingConfig).then(() => { initializingConfig = null; resolveReady(); }, (error) => { initializingConfig = null; rejectReady(error); });
6754
+ void initialize(initializingConfig, fromStorage).then(() => { initializingConfig = null; resolveReady(); }, (error) => { initializingConfig = null; rejectReady(error); });
6585
6755
  return ready;
6586
6756
  }
6587
6757
  /**
@@ -6654,6 +6824,13 @@ function userPrincipalKey(user) {
6654
6824
  }
6655
6825
  // Update the currentUser and notify listeners
6656
6826
  function setCurrentUser(user) {
6827
+ observedIdToken = getCurrentIdToken();
6828
+ try {
6829
+ observedIssuer = getActiveSessionManager().getIssuer();
6830
+ }
6831
+ catch (_a) {
6832
+ observedIssuer = null;
6833
+ }
6657
6834
  // Enrich with the universal identity fields (id/email) derived from the
6658
6835
  // active session's idToken — central chokepoint so every provider's user
6659
6836
  // object gains { id, address, email } without each construction site
@@ -8396,7 +8573,7 @@ class PrivyExpoProvider {
8396
8573
  if (isLegacyTx) {
8397
8574
  const legacyTx = transaction;
8398
8575
  if (!legacyTx.recentBlockhash) {
8399
- const rpcUrl = this.getRpcUrl();
8576
+ const rpcUrl = await this.getRpcUrl();
8400
8577
  const connection = new Connection(rpcUrl, 'confirmed');
8401
8578
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
8402
8579
  legacyTx.recentBlockhash = blockhash;
@@ -8409,7 +8586,7 @@ class PrivyExpoProvider {
8409
8586
  else {
8410
8587
  const versionedTx = transaction;
8411
8588
  if (!versionedTx.message.recentBlockhash) {
8412
- const rpcUrl = this.getRpcUrl();
8589
+ const rpcUrl = await this.getRpcUrl();
8413
8590
  const connection = new Connection(rpcUrl, 'confirmed');
8414
8591
  const { blockhash } = await connection.getLatestBlockhash('confirmed');
8415
8592
  versionedTx.message.recentBlockhash = blockhash;
@@ -8429,7 +8606,7 @@ class PrivyExpoProvider {
8429
8606
  await this.ensureReady();
8430
8607
  const { Connection, PublicKey } = await import('@solana/web3.js');
8431
8608
  const wallet = await this.getWalletOrThrow('submitting this transaction');
8432
- const rpcUrl = this.getRpcUrl();
8609
+ const rpcUrl = await this.getRpcUrl();
8433
8610
  const connection = new Connection(rpcUrl, 'confirmed');
8434
8611
  // Ensure blockhash.
8435
8612
  // DS3-0414: a Solana signature covers the compiled message (recentBlockhash
@@ -8456,8 +8633,9 @@ class PrivyExpoProvider {
8456
8633
  const { signature } = await this.signAndSubmitInternal(transaction, wallet, connection);
8457
8634
  return signature;
8458
8635
  }
8459
- async restoreSession() {
8636
+ async restoreSession(beforeCommit) {
8460
8637
  const session = await getActiveSessionManager().getSession();
8638
+ beforeCommit === null || beforeCommit === void 0 ? void 0 : beforeCommit();
8461
8639
  if (session) {
8462
8640
  this.authenticatedAddress = session.address;
8463
8641
  return { provider: this, address: session.address };
@@ -8530,8 +8708,12 @@ class PrivyExpoProvider {
8530
8708
  const txInfo = await confirmAndCheckTransaction(connection, signature);
8531
8709
  return { signature, txInfo };
8532
8710
  }
8533
- getRpcUrl(network) {
8534
- return resolveSolanaRpcUrl(this.networkUrl, network, "Privy Expo Solana transaction");
8711
+ // The constructor rpcUrl wins, then init()'s rpcUrl, then the platform RPC
8712
+ // for init()'s chain.
8713
+ async getRpcUrl() {
8714
+ var _a;
8715
+ const config = await getConfig();
8716
+ return resolveSolanaRpcUrl((_a = this.networkUrl) !== null && _a !== void 0 ? _a : config.rpcUrl, isSupportedSolanaRpcNetwork(config.chain) ? config.chain : null, "Privy Expo Solana transaction");
8535
8717
  }
8536
8718
  async ensureReady(timeoutMs = 15000) {
8537
8719
  if (!this.privyMethods) {
@@ -8560,4 +8742,4 @@ class PrivyExpoProvider {
8560
8742
  }
8561
8743
 
8562
8744
  export { BUILD_REVIEW_CAPABILITY_SCHEMA as $, logout as A, getAuthProvider as B, signInAnonymously as C, loginWithPrivy as D, loginWithRedirect as E, completeLoginFromRedirect as F, getLoginReturnError as G, loginWithPopup as H, useAuth as I, useQuery as J, useBuildRun as K, apps as L, getIdToken as M, onramp as N, onrampQuote as O, onrampStatus as P, setPlatform as Q, OffchainAuthProvider as R, PrivyExpoProvider as S, builds as T, BuildsApiError as U, mediaAgentTools as V, NON_TERMINAL_STATES as W, TERMINAL_STATES as X, RUN_STATES as Y, PARK_REASONS as Z, FAILURE_REASONS as _, signMessageWithTurnkey as a, BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as a0, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as a1, signTransactionWithTurnkey as b, signTransactionV1WithTurnkey as c, signAndSubmitTransactionWithTurnkey as d, bs58 as e, getWallets as f, getPlatform as g, hasTurnkeyWallet as h, isSolanaMobileWallet as i, solanaMobileWalletLeavesPage as j, setAuthLoading as k, bufferExports as l, setStoredAuthMethod as m, normalizeSolanaRpcUrl as n, confirmAndCheckTransaction as o, resolveSolanaRpcUrl as p, init as q, resolveSolanaWalletStandardChain as r, setCurrentUser as s, transactionHasSignature as t, getCurrentUser as u, onAuthStateChanged as v, onAuthLoadingChanged as w, getAuthLoading as x, waitForAuthReady as y, login as z };
8563
- //# sourceMappingURL=index.native-BSOqaKIz.mjs.map
8745
+ //# sourceMappingURL=index.native-CAH_ks0s.mjs.map