@bounded-sh/client 0.0.48 → 0.0.50

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 (67) hide show
  1. package/README.md +21 -0
  2. package/dist/auth/providers/guest-auth-provider.d.ts +7 -0
  3. package/dist/auth/providers/guest-keystore.d.ts +2 -0
  4. package/dist/builds/apps.d.ts +32 -0
  5. package/dist/builds/client.d.ts +74 -0
  6. package/dist/builds/index.d.ts +20 -0
  7. package/dist/builds/types.d.ts +121 -0
  8. package/dist/builds/watch.d.ts +20 -0
  9. package/dist/{email-auth-provider-GRj8IOg2.mjs → email-auth-provider-B7czfBEU.mjs} +2 -2
  10. package/dist/{email-auth-provider-GRj8IOg2.mjs.map → email-auth-provider-B7czfBEU.mjs.map} +1 -1
  11. package/dist/{email-auth-provider-CmunfauO.js → email-auth-provider-CmYs6Dcm.js} +2 -2
  12. package/dist/{email-auth-provider-CmunfauO.js.map → email-auth-provider-CmYs6Dcm.js.map} +1 -1
  13. package/dist/{email-auth-provider-CTyjwhLb.mjs → email-auth-provider-DIZAETBC.mjs} +2 -2
  14. package/dist/{email-auth-provider-CTyjwhLb.mjs.map → email-auth-provider-DIZAETBC.mjs.map} +1 -1
  15. package/dist/{email-auth-provider-DyxZTpx6.js → email-auth-provider-Dj66AuH0.js} +2 -2
  16. package/dist/{email-auth-provider-DyxZTpx6.js.map → email-auth-provider-Dj66AuH0.js.map} +1 -1
  17. package/dist/global.d.ts +3 -1
  18. package/dist/{guest-auth-provider-D54uHbov.js → guest-auth-provider-B5sgg-q5.js} +98 -14
  19. package/dist/guest-auth-provider-B5sgg-q5.js.map +1 -0
  20. package/dist/{guest-auth-provider-Dk_km5tF.mjs → guest-auth-provider-BR0_YL8z.mjs} +98 -14
  21. package/dist/guest-auth-provider-BR0_YL8z.mjs.map +1 -0
  22. package/dist/{guest-auth-provider-C4BuTNIa.mjs → guest-auth-provider-CCpNvX3j.mjs} +98 -14
  23. package/dist/guest-auth-provider-CCpNvX3j.mjs.map +1 -0
  24. package/dist/{guest-auth-provider-B68XT2lU.js → guest-auth-provider-CxsLCznO.js} +98 -14
  25. package/dist/guest-auth-provider-CxsLCznO.js.map +1 -0
  26. package/dist/hooks/useBuildRun.d.ts +13 -0
  27. package/dist/{index.native-CytJPNQV.mjs → index-BYy1tSkr.mjs} +850 -26
  28. package/dist/index-BYy1tSkr.mjs.map +1 -0
  29. package/dist/{index.native-BZCc0gO-.js → index-m42Be5Oj.js} +861 -24
  30. package/dist/index-m42Be5Oj.js.map +1 -0
  31. package/dist/index.d.ts +5 -0
  32. package/dist/index.js +10 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/index.mjs +1 -1
  35. package/dist/{index-C0pR5b7j.mjs → index.native-B-ldAbu2.mjs} +668 -146
  36. package/dist/index.native-B-ldAbu2.mjs.map +1 -0
  37. package/dist/{index-JBeYYsGm.js → index.native-BfoLJCZg.js} +675 -148
  38. package/dist/index.native-BfoLJCZg.js.map +1 -0
  39. package/dist/index.native.d.ts +5 -0
  40. package/dist/index.native.js +10 -1
  41. package/dist/index.native.js.map +1 -1
  42. package/dist/index.native.mjs +1 -1
  43. package/dist/{injected-evm-wallet-provider-_eeYB1ww.js → injected-evm-wallet-provider-BLQzWiBP.js} +2 -2
  44. package/dist/{injected-evm-wallet-provider-_eeYB1ww.js.map → injected-evm-wallet-provider-BLQzWiBP.js.map} +1 -1
  45. package/dist/{injected-evm-wallet-provider-T-EF9C3W.js → injected-evm-wallet-provider-BXj1YFaZ.js} +2 -2
  46. package/dist/{injected-evm-wallet-provider-T-EF9C3W.js.map → injected-evm-wallet-provider-BXj1YFaZ.js.map} +1 -1
  47. package/dist/{injected-evm-wallet-provider-CxAiNN7R.mjs → injected-evm-wallet-provider-sBCSkksr.mjs} +2 -2
  48. package/dist/{injected-evm-wallet-provider-CxAiNN7R.mjs.map → injected-evm-wallet-provider-sBCSkksr.mjs.map} +1 -1
  49. package/dist/{injected-evm-wallet-provider-BOMLGGHM.mjs → injected-evm-wallet-provider-ubsHX217.mjs} +2 -2
  50. package/dist/{injected-evm-wallet-provider-BOMLGGHM.mjs.map → injected-evm-wallet-provider-ubsHX217.mjs.map} +1 -1
  51. package/dist/{injected-wallet-provider-B1uq3r4r.mjs → injected-wallet-provider-BfzoheDy.mjs} +2 -2
  52. package/dist/{injected-wallet-provider-B1uq3r4r.mjs.map → injected-wallet-provider-BfzoheDy.mjs.map} +1 -1
  53. package/dist/{injected-wallet-provider-B2T7JEvn.js → injected-wallet-provider-Cml9TkyV.js} +2 -2
  54. package/dist/{injected-wallet-provider-B2T7JEvn.js.map → injected-wallet-provider-Cml9TkyV.js.map} +1 -1
  55. package/dist/{injected-wallet-provider-DCwygA3j.mjs → injected-wallet-provider-DG87X6AQ.mjs} +2 -2
  56. package/dist/{injected-wallet-provider-DCwygA3j.mjs.map → injected-wallet-provider-DG87X6AQ.mjs.map} +1 -1
  57. package/dist/{injected-wallet-provider-BBZym7YQ.js → injected-wallet-provider-PYcvLO2Z.js} +2 -2
  58. package/dist/{injected-wallet-provider-BBZym7YQ.js.map → injected-wallet-provider-PYcvLO2Z.js.map} +1 -1
  59. package/package.json +2 -2
  60. package/dist/guest-auth-provider-B68XT2lU.js.map +0 -1
  61. package/dist/guest-auth-provider-C4BuTNIa.mjs.map +0 -1
  62. package/dist/guest-auth-provider-D54uHbov.js.map +0 -1
  63. package/dist/guest-auth-provider-Dk_km5tF.mjs.map +0 -1
  64. package/dist/index-C0pR5b7j.mjs.map +0 -1
  65. package/dist/index-JBeYYsGm.js.map +0 -1
  66. package/dist/index.native-BZCc0gO-.js.map +0 -1
  67. package/dist/index.native-CytJPNQV.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { assertCanonicalBoundedRuntimeWriteCalldata, getActiveSessionManager, getConfig, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, reconnectWithNewAuth, deriveUserIdentityFromIdToken, getIdToken as getIdToken$1, convertRemainingAccounts, buildSetDocumentsTransaction, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
1
+ import { assertCanonicalBoundedRuntimeWriteCalldata, getActiveSessionManager, getConfig, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, reconnectWithNewAuth, deriveUserIdentityFromIdToken, subscribe, getIdToken as getIdToken$1, convertRemainingAccounts, buildSetDocumentsTransaction, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
2
2
  import * as React from 'react';
3
3
 
4
4
  /**
@@ -4226,6 +4226,41 @@ function setStoredAuthMethod(method) {
4226
4226
  // storage might not be available
4227
4227
  }
4228
4228
  }
4229
+ function getStoredIdToken() {
4230
+ try {
4231
+ return getActiveSessionManager().getIdToken();
4232
+ }
4233
+ catch (_a) {
4234
+ return null;
4235
+ }
4236
+ }
4237
+ function idTokenIsGuest(idToken, expectedAddress) {
4238
+ var _a;
4239
+ try {
4240
+ if (!idToken)
4241
+ return false;
4242
+ let b64 = (_a = idToken.split('.')[1]) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '+').replace(/_/g, '/');
4243
+ if (!b64)
4244
+ return false;
4245
+ const pad = b64.length % 4;
4246
+ if (pad === 2)
4247
+ b64 += '==';
4248
+ else if (pad === 3)
4249
+ b64 += '=';
4250
+ const claims = JSON.parse(getPlatform().atob(b64));
4251
+ if ((claims === null || claims === void 0 ? void 0 : claims.is_anonymous) !== true)
4252
+ return false;
4253
+ if (expectedAddress && (claims === null || claims === void 0 ? void 0 : claims['custom:walletAddress']) !== expectedAddress)
4254
+ return false;
4255
+ return true;
4256
+ }
4257
+ catch (_b) {
4258
+ return false;
4259
+ }
4260
+ }
4261
+ function storedSessionIsGuest() {
4262
+ return idTokenIsGuest(getStoredIdToken());
4263
+ }
4229
4264
  /**
4230
4265
  * Pick the provider used for an ordinary `init({ appId })` restore.
4231
4266
  *
@@ -4236,7 +4271,16 @@ function setStoredAuthMethod(method) {
4236
4271
  function authMethodForInit(config) {
4237
4272
  if (config.authMethod != null)
4238
4273
  return config.authMethod;
4239
- return getStoredAuthMethod() === 'guest' ? 'guest' : 'email';
4274
+ if (getStoredAuthMethod() !== 'guest')
4275
+ return 'email';
4276
+ if (storedSessionIsGuest())
4277
+ return 'guest';
4278
+ // A marker is only a restore hint; the bearer is authoritative. Repair a
4279
+ // stale marker (for example, a crash/failed switch while a human session was
4280
+ // still active) instead of relabelling that human bearer as a guest.
4281
+ const hasSession = !!getStoredIdToken();
4282
+ setStoredAuthMethod(hasSession ? 'email' : null);
4283
+ return 'email';
4240
4284
  }
4241
4285
  function objectIdentityKey(value) {
4242
4286
  if (!value || (typeof value !== 'object' && typeof value !== 'function'))
@@ -4401,7 +4445,7 @@ async function getAuthProvider(config) {
4401
4445
  // manager as legacy email sessions. Human login should be started
4402
4446
  // with loginWithRedirect(); this provider is kept as the restore and
4403
4447
  // logout surface for those sessions.
4404
- currentAuthProvider = new (await import('./email-auth-provider-GRj8IOg2.mjs')).EmailAuthProvider();
4448
+ currentAuthProvider = new (await import('./email-auth-provider-DIZAETBC.mjs')).EmailAuthProvider();
4405
4449
  break;
4406
4450
  case "wallet":
4407
4451
  case "phantom": {
@@ -4420,7 +4464,7 @@ async function getAuthProvider(config) {
4420
4464
  if (!isWalletLoginEnabled(config)) {
4421
4465
  throw walletLoginNotEnabledError(authMethod);
4422
4466
  }
4423
- const { InjectedWalletProvider } = await import('./injected-wallet-provider-DCwygA3j.mjs');
4467
+ const { InjectedWalletProvider } = await import('./injected-wallet-provider-BfzoheDy.mjs');
4424
4468
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
4425
4469
  break;
4426
4470
  }
@@ -4433,7 +4477,7 @@ async function getAuthProvider(config) {
4433
4477
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
4434
4478
  // to point at a specific wallet or set chainId/domain.
4435
4479
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
4436
- const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-BOMLGGHM.mjs');
4480
+ const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-sBCSkksr.mjs');
4437
4481
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
4438
4482
  break;
4439
4483
  }
@@ -4461,7 +4505,7 @@ async function getAuthProvider(config) {
4461
4505
  break;
4462
4506
  case "guest":
4463
4507
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
4464
- currentAuthProvider = new (await import('./guest-auth-provider-C4BuTNIa.mjs')).GuestAuthProvider();
4508
+ currentAuthProvider = new (await import('./guest-auth-provider-BR0_YL8z.mjs')).GuestAuthProvider();
4465
4509
  break;
4466
4510
  }
4467
4511
  if (!currentAuthProvider) {
@@ -4498,19 +4542,108 @@ function assertBrowserAuthEnv(method) {
4498
4542
  * ownership-as-data pattern. `init()` must have run first. Browser/RN only.
4499
4543
  */
4500
4544
  async function signInAnonymously() {
4545
+ var _a;
4501
4546
  assertBrowserAuthEnv('signInAnonymously');
4502
- const provider = new (await import('./guest-auth-provider-C4BuTNIa.mjs')).GuestAuthProvider();
4503
- currentAuthProvider = provider;
4504
- currentAuthMethod = 'guest';
4505
- currentAuthProviderConfigKey = 'direct:guest';
4547
+ // Resolve configuration before taking the transaction snapshot. Although
4548
+ // getConfig is normally already resolved after init(), it is asynchronous;
4549
+ // another login that finishes during that await must be part of the prior
4550
+ // state we preserve, not accidentally split across old/new snapshots.
4506
4551
  const coreConfig = await getConfig();
4507
- coreConfig.authProvider = provider;
4508
- coreConfig.authMethod = 'guest';
4509
- setAuthProviderInstance(provider);
4510
- setStoredAuthMethod('guest');
4552
+ const previousAuthProvider = currentAuthProvider;
4553
+ const previousAuthMethod = currentAuthMethod;
4554
+ const previousProviderConfigKey = currentAuthProviderConfigKey;
4555
+ const previousStoredAuthMethod = getStoredAuthMethod();
4556
+ const previousGlobalProvider = getAuthProviderInstance();
4557
+ const previousUser = getCurrentUser();
4558
+ const previousCoreProvider = coreConfig.authProvider;
4559
+ const previousCoreAuthMethod = coreConfig.authMethod;
4560
+ const previousIdToken = getStoredIdToken();
4561
+ // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
4562
+ // the main bundle for data-only apps. Specifier is a static string literal
4563
+ // so bundle-splitting can see it.
4564
+ const provider = new (await import('./guest-auth-provider-BR0_YL8z.mjs')).GuestAuthProvider();
4511
4565
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
4566
+ const commit = (user) => {
4567
+ // No await/interleaving inside this block: provider/method/config/marker
4568
+ // become guest before the user notification fires, so listeners and
4569
+ // concurrent imperative calls can never observe a mixed identity.
4570
+ currentAuthProvider = provider;
4571
+ currentAuthMethod = 'guest';
4572
+ currentAuthProviderConfigKey = 'direct:guest';
4573
+ coreConfig.authProvider = provider;
4574
+ coreConfig.authMethod = 'guest';
4575
+ setAuthProviderInstance(provider);
4576
+ setStoredAuthMethod('guest');
4577
+ setCurrentUser(user);
4578
+ };
4512
4579
  try {
4513
- return await provider.login();
4580
+ // Mint/store first while every shared provider surface remains on the
4581
+ // previous identity. The provider also withholds setCurrentUser here.
4582
+ const user = await provider.loginForProviderSwitch();
4583
+ if (!user)
4584
+ return null;
4585
+ // A human login may have completed after the guest request persisted but
4586
+ // before its promise resumed here. Re-check the live bearer immediately
4587
+ // before commit so a late guest result cannot overwrite that newer user.
4588
+ if (!user.address || !idTokenIsGuest(getStoredIdToken(), user.address)) {
4589
+ throw new Error('Anonymous sign-in was superseded by another session.');
4590
+ }
4591
+ commit(user);
4592
+ return user;
4593
+ }
4594
+ catch (error) {
4595
+ const currentIdToken = getStoredIdToken();
4596
+ if (currentIdToken !== previousIdToken && idTokenIsGuest(currentIdToken)) {
4597
+ // Defensive applied-yet-error reconciliation: if storage contains a
4598
+ // valid guest bearer/key despite the thrown write, commit that truth
4599
+ // instead of restoring a human UI over a guest token.
4600
+ let recovered = null;
4601
+ try {
4602
+ recovered = await provider.restoreSessionForProviderSwitch();
4603
+ }
4604
+ catch (_b) {
4605
+ try {
4606
+ getActiveSessionManager().clearSession();
4607
+ }
4608
+ catch ( /* fail closed below */_c) { /* fail closed below */ }
4609
+ }
4610
+ if (recovered) {
4611
+ commit(recovered);
4612
+ return recovered;
4613
+ }
4614
+ // restoreSessionForProviderSwitch fails closed and clears a split
4615
+ // bearer. Do not resurrect a user object that no longer has its token.
4616
+ setCurrentUser(null);
4617
+ }
4618
+ else if (currentIdToken === previousIdToken) {
4619
+ // The staged attempt never changed the bearer; every shared provider
4620
+ // surface stayed untouched, so restore the exact prior user/marker.
4621
+ currentAuthProvider = previousAuthProvider;
4622
+ currentAuthMethod = previousAuthMethod;
4623
+ currentAuthProviderConfigKey = previousProviderConfigKey;
4624
+ coreConfig.authProvider = previousCoreProvider;
4625
+ coreConfig.authMethod = previousCoreAuthMethod;
4626
+ setAuthProviderInstance(previousGlobalProvider);
4627
+ setStoredAuthMethod(previousStoredAuthMethod);
4628
+ if (getCurrentUser() !== previousUser)
4629
+ setCurrentUser(previousUser);
4630
+ }
4631
+ else {
4632
+ // A different non-guest token won while this staged guest mint was in
4633
+ // flight (another tab/popup/login). The guest attempt never mutated
4634
+ // shared provider state, so preserve that winner exactly. Align only
4635
+ // this module's private registry to the provider the winner installed;
4636
+ // never overwrite its core/global provider, marker, or user snapshot.
4637
+ const concurrentProvider = (_a = getAuthProviderInstance()) !== null && _a !== void 0 ? _a : coreConfig.authProvider;
4638
+ if (concurrentProvider)
4639
+ currentAuthProvider = concurrentProvider;
4640
+ const concurrentStoredMethod = getStoredAuthMethod();
4641
+ currentAuthMethod = concurrentStoredMethod && concurrentStoredMethod !== 'guest'
4642
+ ? concurrentStoredMethod
4643
+ : (previousAuthMethod && previousAuthMethod !== 'guest' ? previousAuthMethod : 'email');
4644
+ currentAuthProviderConfigKey = previousProviderConfigKey;
4645
+ }
4646
+ throw error;
4514
4647
  }
4515
4648
  finally {
4516
4649
  setAuthLoading(false);
@@ -4807,21 +4940,25 @@ function setCurrentUser(user) {
4807
4940
  function getCurrentUser() {
4808
4941
  return currentUser;
4809
4942
  }
4943
+ /** @internal Snapshot/restore surface for transactional auth-provider switches. */
4944
+ function getAuthProviderInstance() {
4945
+ return authProviderInstance;
4946
+ }
4810
4947
  function setAuthProviderInstance(provider) {
4811
4948
  authProviderInstance = provider;
4812
4949
  }
4813
4950
 
4814
- var _a;
4951
+ var _a$2;
4815
4952
  // Whether we're in a server-side rendering context (no hooks allowed).
4816
4953
  // React Native has no `window` but DOES support hooks.
4817
4954
  // We detect Node SSR specifically via process.versions.node to avoid
4818
4955
  // false positives from Node 21+ which defines `navigator` globally.
4819
- const isSSR = typeof window === 'undefined'
4956
+ const isSSR$2 = typeof window === 'undefined'
4820
4957
  && typeof process !== 'undefined'
4821
- && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
4958
+ && !!((_a$2 = process.versions) === null || _a$2 === void 0 ? void 0 : _a$2.node);
4822
4959
  function useAuth() {
4823
4960
  // Provide a fallback so server render doesn't break
4824
- if (isSSR) {
4961
+ if (isSSR$2) {
4825
4962
  return {
4826
4963
  login: async (_options) => undefined,
4827
4964
  logout: async () => undefined,
@@ -4883,6 +5020,613 @@ function useAuth() {
4883
5020
  };
4884
5021
  }
4885
5022
 
5023
+ var _a$1;
5024
+ // SSR guard (mirrors useAuth): no hooks/subscriptions during Node server render.
5025
+ // React Native has no `window` but DOES support hooks, so detect Node SSR
5026
+ // specifically via process.versions.node.
5027
+ const isSSR$1 = typeof window === 'undefined'
5028
+ && typeof process !== 'undefined'
5029
+ && !!((_a$1 = process.versions) === null || _a$1 === void 0 ? void 0 : _a$1.node);
5030
+ function useQuery(path, options) {
5031
+ if (isSSR$1) {
5032
+ return { data: undefined, loading: true, error: null };
5033
+ }
5034
+ const [data, setData] = React.useState(undefined);
5035
+ const [loading, setLoading] = React.useState(true);
5036
+ const [error, setError] = React.useState(null);
5037
+ // Re-subscribe only when the query actually changes (not on every render).
5038
+ const optionsKey = options ? JSON.stringify(options) : '';
5039
+ React.useEffect(() => {
5040
+ if (!path) {
5041
+ setData(undefined);
5042
+ setLoading(false);
5043
+ setError(null);
5044
+ return;
5045
+ }
5046
+ let active = true;
5047
+ let unsubscribe;
5048
+ setLoading(true);
5049
+ setError(null);
5050
+ subscribe(path, Object.assign(Object.assign({}, options), { onData: (d) => {
5051
+ if (!active)
5052
+ return;
5053
+ // A reconnect can legitimately surface a transport error before the
5054
+ // socket re-authenticates and sends a new authorized snapshot. That
5055
+ // fresh snapshot is the recovery boundary: keep the error visible
5056
+ // until data arrives, then clear it so React does not remain stuck on
5057
+ // a failure page after realtime has recovered.
5058
+ setError(null);
5059
+ setData(d);
5060
+ setLoading(false);
5061
+ }, onError: (e) => {
5062
+ if (!active)
5063
+ return;
5064
+ setError(e instanceof Error ? e : new Error(String(e)));
5065
+ setLoading(false);
5066
+ } }))
5067
+ .then((unsub) => {
5068
+ if (active)
5069
+ unsubscribe = unsub;
5070
+ else
5071
+ void unsub(); // unmounted before subscribe resolved
5072
+ })
5073
+ .catch((e) => {
5074
+ if (!active)
5075
+ return;
5076
+ setError(e instanceof Error ? e : new Error(String(e)));
5077
+ setLoading(false);
5078
+ });
5079
+ return () => {
5080
+ active = false;
5081
+ void (unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe());
5082
+ };
5083
+ // optionsKey captures the option object's contents; path is the other input.
5084
+ // eslint-disable-next-line react-hooks/exhaustive-deps
5085
+ }, [path, optionsKey]);
5086
+ return { data, loading, error };
5087
+ }
5088
+
5089
+ // Wrapper for getIdToken - passes isServer=false for client-side usage
5090
+ async function getIdToken() {
5091
+ return getIdToken$1(false);
5092
+ }
5093
+
5094
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
5095
+ var t = {};
5096
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5097
+ t[p] = s[p];
5098
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
5099
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
5100
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
5101
+ t[p[i]] = s[p[i]];
5102
+ }
5103
+ return t;
5104
+ };
5105
+ /** A structured non-2xx response from the developer API. */
5106
+ class BuildsApiError extends Error {
5107
+ constructor(init) {
5108
+ super(init.message);
5109
+ this.name = 'BuildsApiError';
5110
+ this.code = init.code;
5111
+ this.retryable = init.retryable;
5112
+ this.status = init.status;
5113
+ this.details = init.details;
5114
+ this.retryAfterMs = init.retryAfterMs;
5115
+ }
5116
+ }
5117
+ const memoryIdempotencyKeys = new Map();
5118
+ const IDEMPOTENCY_STORAGE_PREFIX = 'bounded:build:idempotency:';
5119
+ function retryAfterMs(response) {
5120
+ var _a, _b;
5121
+ const value = (_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, 'Retry-After');
5122
+ if (!value)
5123
+ return undefined;
5124
+ const seconds = Number(value);
5125
+ if (Number.isFinite(seconds) && seconds >= 0)
5126
+ return Math.ceil(seconds * 1000);
5127
+ const at = Date.parse(value);
5128
+ if (!Number.isFinite(at))
5129
+ return undefined;
5130
+ return Math.max(0, at - Date.now());
5131
+ }
5132
+ async function responseBody(response) {
5133
+ const text = await response.text();
5134
+ if (!text)
5135
+ return {};
5136
+ try {
5137
+ return JSON.parse(text);
5138
+ }
5139
+ catch (_a) {
5140
+ return { raw: text };
5141
+ }
5142
+ }
5143
+ function apiError(response, body) {
5144
+ const envelope = body;
5145
+ const nested = (envelope === null || envelope === void 0 ? void 0 : envelope.error) && typeof envelope.error === 'object'
5146
+ ? envelope.error
5147
+ : undefined;
5148
+ const hasNestedDetails = !!nested && Object.prototype.hasOwnProperty.call(nested, 'details');
5149
+ const hasTopLevelDetails = !!body
5150
+ && typeof body === 'object'
5151
+ && Object.prototype.hasOwnProperty.call(body, 'details');
5152
+ const legacyCode = typeof (body === null || body === void 0 ? void 0 : body.error) === 'string' ? body.error : undefined;
5153
+ const code = typeof (nested === null || nested === void 0 ? void 0 : nested.code) === 'string'
5154
+ ? nested.code
5155
+ : legacyCode !== null && legacyCode !== void 0 ? legacyCode : `http_${response.status}`;
5156
+ const message = typeof (nested === null || nested === void 0 ? void 0 : nested.message) === 'string'
5157
+ ? nested.message
5158
+ : typeof (body === null || body === void 0 ? void 0 : body.message) === 'string'
5159
+ ? body.message
5160
+ : `Developer API request failed with HTTP ${response.status}`;
5161
+ const retryable = typeof (nested === null || nested === void 0 ? void 0 : nested.retryable) === 'boolean'
5162
+ ? nested.retryable
5163
+ : response.status === 429 || response.status >= 500;
5164
+ return new BuildsApiError(Object.assign(Object.assign({ code,
5165
+ message,
5166
+ retryable, status: response.status }, (hasNestedDetails
5167
+ ? { details: nested === null || nested === void 0 ? void 0 : nested.details }
5168
+ : hasTopLevelDetails
5169
+ ? { details: body.details }
5170
+ : {})), (response.status === 429 ? { retryAfterMs: retryAfterMs(response) } : {})));
5171
+ }
5172
+ /** @internal Shared authenticated developer-api transport for builds and apps. */
5173
+ async function requestDevApi(path, request = {}) {
5174
+ var _a, _b;
5175
+ const config = await getConfig();
5176
+ const base = (_a = config.devApiUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/$/, '');
5177
+ if (!base) {
5178
+ throw new Error('Bounded developer API is not configured. Pass devApiUrl or a Bounded network to init().');
5179
+ }
5180
+ // Reuse the exact accessor exposed publicly as getIdToken().
5181
+ const token = await getIdToken();
5182
+ if (!token) {
5183
+ throw new BuildsApiError({
5184
+ code: 'auth_required',
5185
+ message: 'Sign in before calling the Bounded developer API.',
5186
+ retryable: false,
5187
+ status: 401,
5188
+ });
5189
+ }
5190
+ const hasBody = request.body !== undefined;
5191
+ const response = await fetch(`${base}${path}`, Object.assign({ method: (_b = request.method) !== null && _b !== void 0 ? _b : 'GET', headers: Object.assign({ Authorization: `Bearer ${token}` }, (hasBody ? { 'Content-Type': 'application/json' } : {})) }, (hasBody ? { body: JSON.stringify(request.body) } : {})));
5192
+ const body = await responseBody(response);
5193
+ if (!response.ok)
5194
+ throw apiError(response, body);
5195
+ return body;
5196
+ }
5197
+ function intentStorageKey(intentKey) {
5198
+ return `${IDEMPOTENCY_STORAGE_PREFIX}${intentKey}`;
5199
+ }
5200
+ function isValidIdempotencyKey(value) {
5201
+ return typeof value === 'string' && value.length > 0 && value.length <= 256;
5202
+ }
5203
+ function readPersistedIdempotencyKey(intentKey) {
5204
+ var _a;
5205
+ const storageKey = intentStorageKey(intentKey);
5206
+ try {
5207
+ const stored = (_a = globalThis.sessionStorage) === null || _a === void 0 ? void 0 : _a.getItem(storageKey);
5208
+ if (isValidIdempotencyKey(stored))
5209
+ return stored;
5210
+ }
5211
+ catch (_b) {
5212
+ // Storage can be disabled by browser privacy policy; use module memory.
5213
+ }
5214
+ const inMemory = memoryIdempotencyKeys.get(storageKey);
5215
+ return isValidIdempotencyKey(inMemory) ? inMemory : undefined;
5216
+ }
5217
+ function persistIdempotencyKey(intentKey, idempotencyKey) {
5218
+ var _a;
5219
+ const storageKey = intentStorageKey(intentKey);
5220
+ memoryIdempotencyKeys.set(storageKey, idempotencyKey);
5221
+ try {
5222
+ (_a = globalThis.sessionStorage) === null || _a === void 0 ? void 0 : _a.setItem(storageKey, idempotencyKey);
5223
+ }
5224
+ catch (_b) {
5225
+ // The in-memory write above is the React Native / disabled-storage fallback.
5226
+ }
5227
+ }
5228
+ function randomHex(bytes) {
5229
+ const cryptoObject = globalThis.crypto;
5230
+ if (cryptoObject === null || cryptoObject === void 0 ? void 0 : cryptoObject.getRandomValues) {
5231
+ const values = new Uint8Array(bytes);
5232
+ cryptoObject.getRandomValues(values);
5233
+ return Array.from(values, (value) => value.toString(16).padStart(2, '0')).join('');
5234
+ }
5235
+ let value = '';
5236
+ for (let index = 0; index < bytes; index += 1) {
5237
+ value += Math.floor(Math.random() * 256).toString(16).padStart(2, '0');
5238
+ }
5239
+ return value;
5240
+ }
5241
+ function mintIdempotencyKey() {
5242
+ const cryptoObject = globalThis.crypto;
5243
+ if (typeof (cryptoObject === null || cryptoObject === void 0 ? void 0 : cryptoObject.randomUUID) === 'function') {
5244
+ return `build_${cryptoObject.randomUUID()}`;
5245
+ }
5246
+ return `build_${Date.now().toString(36)}_${randomHex(16)}`;
5247
+ }
5248
+ function actionIdempotencyKey(options, action) {
5249
+ const supplied = options.idempotencyKey;
5250
+ if (supplied !== undefined) {
5251
+ if (!isValidIdempotencyKey(supplied)) {
5252
+ throw new TypeError('idempotencyKey must be between 1 and 256 characters.');
5253
+ }
5254
+ if (options.intentKey)
5255
+ persistIdempotencyKey(options.intentKey, supplied);
5256
+ return supplied;
5257
+ }
5258
+ if (!options.intentKey) {
5259
+ throw new TypeError(`intentKey is required when ${action} auto-mints an idempotency key.`);
5260
+ }
5261
+ const existing = readPersistedIdempotencyKey(options.intentKey);
5262
+ if (existing)
5263
+ return existing;
5264
+ const minted = mintIdempotencyKey();
5265
+ // This is deliberately synchronous and happens before requestDevApi can fetch.
5266
+ persistIdempotencyKey(options.intentKey, minted);
5267
+ return minted;
5268
+ }
5269
+ function appPath(appId) {
5270
+ return `/app/${encodeURIComponent(appId)}/builds`;
5271
+ }
5272
+ async function submit(appId, options) {
5273
+ const idempotencyKey = actionIdempotencyKey(options, 'submit()');
5274
+ const { intentKey: _intentKey, idempotencyKey: _suppliedKey } = options, submission = __rest(options, ["intentKey", "idempotencyKey"]);
5275
+ return requestDevApi(appPath(appId), {
5276
+ method: 'POST',
5277
+ body: Object.assign(Object.assign({}, submission), { idempotencyKey }),
5278
+ });
5279
+ }
5280
+ async function get(appId, runId) {
5281
+ return requestDevApi(`${appPath(appId)}/${encodeURIComponent(runId)}`);
5282
+ }
5283
+ async function events(appId, runId, after = 0) {
5284
+ const cursor = Number.isFinite(after) ? Math.max(0, Math.floor(after)) : 0;
5285
+ return requestDevApi(`${appPath(appId)}/${encodeURIComponent(runId)}/events?after=${cursor}`);
5286
+ }
5287
+ async function cancel(appId, runId) {
5288
+ return requestDevApi(`${appPath(appId)}/${encodeURIComponent(runId)}/cancel`, { method: 'POST' });
5289
+ }
5290
+ async function decideGate(appId, runId, gateId, options) {
5291
+ const idempotencyKey = actionIdempotencyKey(options, 'decideGate()');
5292
+ const { intentKey: _intentKey, idempotencyKey: _suppliedKey } = options, decision = __rest(options, ["intentKey", "idempotencyKey"]);
5293
+ return requestDevApi(`${appPath(appId)}/${encodeURIComponent(runId)}/gates/${encodeURIComponent(gateId)}/decision`, { method: 'POST', body: Object.assign(Object.assign({}, decision), { idempotencyKey }) });
5294
+ }
5295
+ async function topup(appId, runId, options) {
5296
+ return requestDevApi(`${appPath(appId)}/${encodeURIComponent(runId)}/topup`, { method: 'POST', body: options });
5297
+ }
5298
+ async function list$1(appId, limit = 20) {
5299
+ const requestedLimit = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 20;
5300
+ return requestDevApi(`${appPath(appId)}?limit=${requestedLimit}`);
5301
+ }
5302
+
5303
+ // Source of truth for these strings:
5304
+ // packages/cdk/cloudflare/bounded-build/src/types.ts. Keep them string-pinned;
5305
+ // wire:1 remains additive and callers must tolerate unknown response strings.
5306
+ const NON_TERMINAL_STATES = [
5307
+ 'queued',
5308
+ 'admitted',
5309
+ 'executing',
5310
+ 'preview_ready',
5311
+ 'parked',
5312
+ 'resuming',
5313
+ 'promoting',
5314
+ 'quarantined',
5315
+ ];
5316
+ const TERMINAL_STATES = [
5317
+ 'promoted',
5318
+ 'failed',
5319
+ 'canceled',
5320
+ 'rejected',
5321
+ 'expired',
5322
+ 'rebase_required',
5323
+ 'reported',
5324
+ ];
5325
+ const RUN_STATES = [
5326
+ ...NON_TERMINAL_STATES,
5327
+ ...TERMINAL_STATES,
5328
+ ];
5329
+ const PARK_REASONS = ['gate', 'funding'];
5330
+ const FAILURE_REASONS = [
5331
+ 'admission_rejected',
5332
+ 'dispatch_timeout',
5333
+ 'auth_revoked',
5334
+ 'owner_changed',
5335
+ 'policy_changed',
5336
+ 'quarantine_forced',
5337
+ 'bind_failed',
5338
+ 'internal_error',
5339
+ ];
5340
+
5341
+ const NORMAL_POLL_MS = 2000;
5342
+ const PARKED_POLL_MS = 5000;
5343
+ const LONG_RUNNING_POLL_MS = 10000;
5344
+ const TWO_MINUTES_MS = 2 * 60000;
5345
+ const TEN_MINUTES_MS = 10 * 60000;
5346
+ const terminalStates = new Set(TERMINAL_STATES);
5347
+ function pollCadence(state, elapsedMs) {
5348
+ if (elapsedMs >= TEN_MINUTES_MS)
5349
+ return LONG_RUNNING_POLL_MS;
5350
+ if ((state === null || state === void 0 ? void 0 : state.startsWith('parked')) || elapsedMs >= TWO_MINUTES_MS)
5351
+ return PARKED_POLL_MS;
5352
+ return NORMAL_POLL_MS;
5353
+ }
5354
+ function retryCadence(error, state, elapsedMs) {
5355
+ const cadence = pollCadence(state, elapsedMs);
5356
+ if (error instanceof BuildsApiError && error.status === 429 && error.retryAfterMs !== undefined) {
5357
+ return Math.max(cadence, error.retryAfterMs);
5358
+ }
5359
+ return cadence;
5360
+ }
5361
+ function hasRetryAfter(error) {
5362
+ return error instanceof BuildsApiError
5363
+ && error.status === 429
5364
+ && error.retryAfterMs !== undefined;
5365
+ }
5366
+ // A permanent API refusal (expired session, revoked access, unknown run) will
5367
+ // never heal by re-polling; the loop must stop and surface it instead of
5368
+ // retrying forever. 429 stays retryable regardless of the server envelope.
5369
+ function isPermanentError(error) {
5370
+ return error instanceof BuildsApiError
5371
+ && error.status !== 429
5372
+ && error.retryable === false;
5373
+ }
5374
+ function newEvents(rows, lastSeq, seen) {
5375
+ const cursorBeforePoll = lastSeq;
5376
+ const fresh = [];
5377
+ let nextCursor = lastSeq;
5378
+ for (const event of rows) {
5379
+ if (!Number.isFinite(event === null || event === void 0 ? void 0 : event.seq))
5380
+ continue;
5381
+ nextCursor = Math.max(nextCursor, event.seq);
5382
+ if (event.seq <= cursorBeforePoll || seen.has(event.seq))
5383
+ continue;
5384
+ seen.add(event.seq);
5385
+ fresh.push(event);
5386
+ }
5387
+ return { events: fresh, lastSeq: nextCursor };
5388
+ }
5389
+ /**
5390
+ * Poll a build view and its event cursor until stopped or the run reaches a
5391
+ * known terminal state. Unknown state strings remain untouched and nonterminal.
5392
+ */
5393
+ function watch(appId, runId, onUpdate, options = {}) {
5394
+ const startedAt = Date.now();
5395
+ const seenSeqs = new Set();
5396
+ let lastSeq = Number.isFinite(options.after)
5397
+ ? Math.max(0, Math.floor(options.after))
5398
+ : 0;
5399
+ let timer;
5400
+ let active = true;
5401
+ let lastState;
5402
+ const stop = () => {
5403
+ active = false;
5404
+ if (timer !== undefined) {
5405
+ clearTimeout(timer);
5406
+ timer = undefined;
5407
+ }
5408
+ };
5409
+ const schedule = (delayMs) => {
5410
+ if (!active)
5411
+ return;
5412
+ timer = setTimeout(() => {
5413
+ timer = undefined;
5414
+ void poll();
5415
+ }, delayMs);
5416
+ };
5417
+ const reportError = (error) => {
5418
+ var _a;
5419
+ try {
5420
+ (_a = options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
5421
+ }
5422
+ catch (_b) {
5423
+ // A consumer error callback must not break the transport loop.
5424
+ }
5425
+ };
5426
+ const publish = (run, events) => {
5427
+ try {
5428
+ onUpdate({ run, events });
5429
+ }
5430
+ catch (_a) {
5431
+ // Polling is transport state; consumer render errors must not strand it.
5432
+ }
5433
+ };
5434
+ const poll = async () => {
5435
+ if (!active)
5436
+ return;
5437
+ let run;
5438
+ try {
5439
+ const view = await get(appId, runId);
5440
+ if (!active)
5441
+ return;
5442
+ run = view.run;
5443
+ lastState = run.state;
5444
+ }
5445
+ catch (error) {
5446
+ if (!active)
5447
+ return;
5448
+ reportError(error);
5449
+ if (isPermanentError(error)) {
5450
+ stop();
5451
+ return;
5452
+ }
5453
+ schedule(retryCadence(error, lastState, Date.now() - startedAt));
5454
+ return;
5455
+ }
5456
+ try {
5457
+ const response = await events(appId, runId, lastSeq);
5458
+ if (!active)
5459
+ return;
5460
+ const deduped = newEvents(Array.isArray(response.events) ? response.events : [], lastSeq, seenSeqs);
5461
+ lastSeq = deduped.lastSeq;
5462
+ publish(run, deduped.events);
5463
+ }
5464
+ catch (error) {
5465
+ if (!active)
5466
+ return;
5467
+ // The view still advances UI state even when event replay is rate-limited.
5468
+ publish(run, []);
5469
+ reportError(error);
5470
+ if (terminalStates.has(run.state)) {
5471
+ // The run itself is done, but a rate-limited final event replay still
5472
+ // owes the caller its unseen seq rows. Honor Retry-After, retry the
5473
+ // piggyback once the limiter permits it, then stop after a successful
5474
+ // replay. Other terminal replay failures stop normally.
5475
+ if (hasRetryAfter(error)) {
5476
+ schedule(retryCadence(error, run.state, Date.now() - startedAt));
5477
+ return;
5478
+ }
5479
+ stop();
5480
+ return;
5481
+ }
5482
+ if (isPermanentError(error)) {
5483
+ stop();
5484
+ return;
5485
+ }
5486
+ schedule(retryCadence(error, run.state, Date.now() - startedAt));
5487
+ return;
5488
+ }
5489
+ if (!active)
5490
+ return;
5491
+ if (terminalStates.has(run.state)) {
5492
+ // Drain the remaining event pages before stopping: a resumed terminal
5493
+ // watch may owe the caller more rows than one page returns. Each page
5494
+ // advances the cursor, so the loop terminates; the cap is a backstop.
5495
+ for (let page = 0; page < 50 && active; page += 1) {
5496
+ let drained;
5497
+ try {
5498
+ const response = await events(appId, runId, lastSeq);
5499
+ if (!active)
5500
+ return;
5501
+ drained = newEvents(Array.isArray(response.events) ? response.events : [], lastSeq, seenSeqs);
5502
+ }
5503
+ catch (error) {
5504
+ reportError(error);
5505
+ break;
5506
+ }
5507
+ if (drained.events.length === 0)
5508
+ break;
5509
+ lastSeq = drained.lastSeq;
5510
+ publish(run, drained.events);
5511
+ }
5512
+ stop();
5513
+ return;
5514
+ }
5515
+ schedule(pollCadence(run.state, Date.now() - startedAt));
5516
+ };
5517
+ void poll();
5518
+ return { stop };
5519
+ }
5520
+
5521
+ var _a;
5522
+ // SSR guard (mirrors useAuth): no hooks/subscriptions during Node server render.
5523
+ // React Native has no `window` but DOES support hooks, so detect Node SSR
5524
+ // specifically via process.versions.node.
5525
+ const isSSR = typeof window === 'undefined'
5526
+ && typeof process !== 'undefined'
5527
+ && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
5528
+ function useBuildRun(appId, runId, options) {
5529
+ if (isSSR) {
5530
+ return { run: null, events: [], loading: true, error: null };
5531
+ }
5532
+ const [run, setRun] = React.useState(null);
5533
+ const [events, setEvents] = React.useState([]);
5534
+ const [loading, setLoading] = React.useState(true);
5535
+ const [error, setError] = React.useState(null);
5536
+ const optionsKey = options ? JSON.stringify(options) : '';
5537
+ React.useEffect(() => {
5538
+ setRun(null);
5539
+ setEvents([]);
5540
+ setError(null);
5541
+ if (!appId || !runId) {
5542
+ setLoading(false);
5543
+ return;
5544
+ }
5545
+ let active = true;
5546
+ setLoading(true);
5547
+ const handle = watch(appId, runId, ({ run: nextRun, events: nextEvents }) => {
5548
+ if (!active)
5549
+ return;
5550
+ setRun(nextRun);
5551
+ if (nextEvents.length > 0) {
5552
+ setEvents((current) => {
5553
+ const seen = new Set(current.map((event) => event.seq));
5554
+ return [...current, ...nextEvents.filter((event) => !seen.has(event.seq))];
5555
+ });
5556
+ }
5557
+ setError(null);
5558
+ setLoading(false);
5559
+ }, Object.assign(Object.assign({}, options), { onError: (value) => {
5560
+ if (!active)
5561
+ return;
5562
+ setError(value instanceof Error ? value : new Error(String(value)));
5563
+ setLoading(false);
5564
+ } }));
5565
+ return () => {
5566
+ active = false;
5567
+ handle.stop();
5568
+ };
5569
+ // optionsKey captures the option object's contents; ids are the other inputs.
5570
+ // eslint-disable-next-line react-hooks/exhaustive-deps
5571
+ }, [appId, runId, optionsKey]);
5572
+ return { run, events, loading, error };
5573
+ }
5574
+
5575
+ /**
5576
+ * Platform first-party surfaces only (bounded.sh, oapps.fun, localhost) —
5577
+ * dev-api CORS blocks calls from generated-app origins. Server-side callers unaffected.
5578
+ */
5579
+ const builds = {
5580
+ submit,
5581
+ get,
5582
+ events,
5583
+ cancel,
5584
+ decideGate,
5585
+ topup,
5586
+ list: list$1,
5587
+ watch,
5588
+ };
5589
+
5590
+ async function create(options = {}) {
5591
+ const body = Object.assign(Object.assign(Object.assign(Object.assign({}, (options.name !== undefined ? { name: options.name } : {})), (options.prompt !== undefined ? { prompt: options.prompt } : {})), (options.clientToken !== undefined ? { clientToken: options.clientToken } : {})), (options.intent !== undefined ? { intent: options.intent } : {}));
5592
+ const app = await requestDevApi('/apps/new', {
5593
+ method: 'POST',
5594
+ body,
5595
+ });
5596
+ return Object.assign(Object.assign({ appId: app.appId }, (typeof app.slug === 'string' && app.slug ? { slug: app.slug } : {})), { url: app.url,
5597
+ // Fail closed against an older server response that omitted this field.
5598
+ policySeeded: app.policySeeded === true });
5599
+ }
5600
+ async function list() {
5601
+ // This legacy-compatible action shape is also used by oapps.fun listMyApps.
5602
+ const response = await requestDevApi('/', {
5603
+ method: 'POST',
5604
+ body: { action: 'listApps' },
5605
+ });
5606
+ const rows = Array.isArray(response.apps) ? response.apps : [];
5607
+ return rows
5608
+ .map((value) => {
5609
+ var _a, _b, _c, _d;
5610
+ const row = value && typeof value === 'object'
5611
+ ? value
5612
+ : {};
5613
+ const appId = String((_c = (_b = (_a = row._id) !== null && _a !== void 0 ? _a : row.id) !== null && _b !== void 0 ? _b : row.appId) !== null && _c !== void 0 ? _c : '');
5614
+ if (!/^[a-f0-9]{24}$/i.test(appId))
5615
+ return null;
5616
+ const name = String((_d = row.name) !== null && _d !== void 0 ? _d : '').trim() || '(unnamed app)';
5617
+ const slug = typeof row.slug === 'string' && row.slug ? row.slug : undefined;
5618
+ const url = typeof row.url === 'string' && row.url.trim() ? row.url.trim() : undefined;
5619
+ return Object.assign(Object.assign({ appId,
5620
+ name }, (slug ? { slug } : {})), (url ? { url } : {}));
5621
+ })
5622
+ .filter((app) => app !== null);
5623
+ }
5624
+ /**
5625
+ * Platform first-party surfaces only (bounded.sh, oapps.fun, localhost) —
5626
+ * dev-api CORS blocks calls from generated-app origins. Server-side callers unaffected.
5627
+ */
5628
+ const apps = { create, list };
5629
+
4886
5630
  async function deserializeTransaction(tx) {
4887
5631
  // Literal specifier so bundlers can code-split the lazy chunk.
4888
5632
  const { Transaction, VersionedTransaction } = await import('@solana/web3.js');
@@ -4895,11 +5639,6 @@ async function deserializeTransaction(tx) {
4895
5639
  }
4896
5640
  }
4897
5641
 
4898
- // Wrapper for getIdToken - passes isServer=false for client-side usage
4899
- async function getIdToken() {
4900
- return getIdToken$1(false);
4901
- }
4902
-
4903
5642
  /**
4904
5643
  * Extracts a human-readable error message from Solana transaction logs.
4905
5644
  */
@@ -5295,5 +6034,90 @@ class PrivyExpoProvider {
5295
6034
  }
5296
6035
  }
5297
6036
 
5298
- export { useAuth as A, deserializeTransaction as B, getIdToken as C, setPlatform as D, EMBEDDED_WALLET_UNSUPPORTED as E, OffchainAuthProvider as O, PrivyExpoProvider as P, SURFNET_RPC_URL as S, hasEmbeddedEvmWallet as a, embeddedSignAndSubmit as b, setAuthLoading as c, bufferExports as d, embeddedRunEvmTransaction as e, bs58 as f, getPlatform as g, hasEmbeddedWallet as h, confirmAndCheckTransaction as i, init as j, getCurrentUser as k, onAuthLoadingChanged as l, getAuthLoading as m, normalizeSolanaRpcUrl as n, onAuthStateChanged as o, login as p, logout as q, resolveSolanaRpcUrl as r, setCurrentUser as s, getAuthProvider as t, signInAnonymously as u, loginWithPrivy as v, loginWithRedirect as w, completeLoginFromRedirect as x, loginWithPopup as y, completeLoginInPopup as z };
5299
- //# sourceMappingURL=index.native-CytJPNQV.mjs.map
6037
+ /**
6038
+ * Default provider discovery: Phantom-first, then any Wallet-Standard
6039
+ * `window.solana`. Kept tiny + synchronous (no heavy imports) so it works inside
6040
+ * a user gesture and can be eagerly exported from the SDK entry.
6041
+ */
6042
+ function defaultInjectedProvider() {
6043
+ var _a;
6044
+ if (typeof window === 'undefined')
6045
+ return null;
6046
+ const w = window;
6047
+ const phantom = (_a = w === null || w === void 0 ? void 0 : w.phantom) === null || _a === void 0 ? void 0 : _a.solana;
6048
+ if (phantom && typeof phantom.signMessage === 'function')
6049
+ return phantom;
6050
+ const generic = w === null || w === void 0 ? void 0 : w.solana;
6051
+ if (generic && typeof generic.signMessage === 'function')
6052
+ return generic;
6053
+ return null;
6054
+ }
6055
+
6056
+ // injected-evm-wallet-types.ts — tiny, dependency-free surface for the EVM
6057
+ // WALLET LOGIN path (BYO wallet via SIWE). The EVM twin of
6058
+ // injected-wallet-types.ts: kept separate from injected-evm-wallet-provider.ts
6059
+ // so the SDK entry can eagerly export the type surface + the provider-discovery
6060
+ // helper WITHOUT dragging the provider class into the default bundle. The
6061
+ // provider is lazy-loaded by getAuthProvider() when an app opts into
6062
+ // authMethod:'evm-wallet'.
6063
+ //
6064
+ // It rides the standard EIP-1193 injected provider a browser wallet exposes
6065
+ // (MetaMask / Rabby / Coinbase Wallet / any window.ethereum), discovered via
6066
+ // EIP-6963 (multi-wallet, collision-free) with a window.ethereum fallback. It
6067
+ // needs NO viem/ethers and NO React — EIP-1193 request() + hex strings suffice.
6068
+ // EIP-6963 is announcement-based: wallets add an `eip6963:requestProvider`
6069
+ // listener and synchronously dispatch `eip6963:announceProvider` in response. We
6070
+ // keep a persistent collector so announcements (including late ones) are
6071
+ // captured, and re-request on demand.
6072
+ const announcedProviders = [];
6073
+ let announceListenerAttached = false;
6074
+ function attachAnnounceListener() {
6075
+ if (announceListenerAttached || typeof window === 'undefined')
6076
+ return;
6077
+ announceListenerAttached = true;
6078
+ window.addEventListener('eip6963:announceProvider', (event) => {
6079
+ const detail = event === null || event === void 0 ? void 0 : event.detail;
6080
+ if (detail &&
6081
+ detail.provider &&
6082
+ typeof detail.provider.request === 'function' &&
6083
+ !announcedProviders.some((d) => { var _a, _b; return ((_a = d.info) === null || _a === void 0 ? void 0 : _a.uuid) === ((_b = detail.info) === null || _b === void 0 ? void 0 : _b.uuid); })) {
6084
+ announcedProviders.push(detail);
6085
+ }
6086
+ });
6087
+ }
6088
+ /**
6089
+ * Request + collect EIP-6963 providers. Dispatches `eip6963:requestProvider`
6090
+ * (synchronous — already-loaded wallets announce in the same tick) and returns
6091
+ * every wallet announced so far. Kept synchronous so it works inside a user
6092
+ * gesture and can be eagerly exported from the SDK entry.
6093
+ */
6094
+ function requestEip6963Providers() {
6095
+ if (typeof window === 'undefined')
6096
+ return [];
6097
+ attachAnnounceListener();
6098
+ try {
6099
+ window.dispatchEvent(new Event('eip6963:requestProvider'));
6100
+ }
6101
+ catch (_a) {
6102
+ /* older browsers without Event constructor — fall through to window.ethereum */
6103
+ }
6104
+ return announcedProviders.slice();
6105
+ }
6106
+ /**
6107
+ * Default EVM provider discovery: EIP-6963 first (multi-wallet, collision-free),
6108
+ * then legacy `window.ethereum`. Returns null when no injected wallet is present.
6109
+ */
6110
+ function defaultInjectedEvmProvider() {
6111
+ if (typeof window === 'undefined')
6112
+ return null;
6113
+ const details = requestEip6963Providers();
6114
+ if (details.length > 0)
6115
+ return details[0].provider;
6116
+ const eth = window.ethereum;
6117
+ if (eth && typeof eth.request === 'function')
6118
+ return eth;
6119
+ return null;
6120
+ }
6121
+
6122
+ export { loginWithPopup as A, completeLoginInPopup as B, useAuth as C, useQuery as D, EMBEDDED_WALLET_UNSUPPORTED as E, useBuildRun as F, apps as G, deserializeTransaction as H, getIdToken as I, setPlatform as J, requestEip6963Providers as K, builds as L, BuildsApiError as M, NON_TERMINAL_STATES as N, OffchainAuthProvider as O, PrivyExpoProvider as P, PARK_REASONS as Q, RUN_STATES as R, SURFNET_RPC_URL as S, TERMINAL_STATES as T, FAILURE_REASONS as U, hasEmbeddedEvmWallet as a, embeddedSignAndSubmit as b, setAuthLoading as c, defaultInjectedProvider as d, embeddedRunEvmTransaction as e, bufferExports as f, getPlatform as g, hasEmbeddedWallet as h, bs58 as i, confirmAndCheckTransaction as j, defaultInjectedEvmProvider as k, init as l, getCurrentUser as m, normalizeSolanaRpcUrl as n, onAuthStateChanged as o, onAuthLoadingChanged as p, getAuthLoading as q, resolveSolanaRpcUrl as r, setCurrentUser as s, login as t, logout as u, getAuthProvider as v, signInAnonymously as w, loginWithPrivy as x, loginWithRedirect as y, completeLoginFromRedirect as z };
6123
+ //# sourceMappingURL=index-BYy1tSkr.mjs.map