@bounded-sh/client 0.0.118-openapps.0 → 0.0.119

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 (60) hide show
  1. package/dist/auth/providers/email-auth-provider.d.ts +2 -1
  2. package/dist/auth/providers/offchain-auth-provider.d.ts +2 -1
  3. package/dist/auth/providers/transaction-utils.d.ts +5 -3
  4. package/dist/auth/turnkey-signer-bridge.d.ts +16 -0
  5. package/dist/auth/turnkey-wallet-widget.d.ts +4 -0
  6. package/dist/{email-auth-provider-C5bYKzpN.mjs → email-auth-provider-DHq5_wtn.mjs} +7 -2
  7. package/dist/email-auth-provider-DHq5_wtn.mjs.map +1 -0
  8. package/dist/{email-auth-provider-C-SGTRZe.mjs → email-auth-provider-DOI-4lPC.mjs} +7 -2
  9. package/dist/email-auth-provider-DOI-4lPC.mjs.map +1 -0
  10. package/dist/{email-auth-provider-CjbJ8wK1.js → email-auth-provider-DyzhiN9Y.js} +7 -2
  11. package/dist/email-auth-provider-DyzhiN9Y.js.map +1 -0
  12. package/dist/{email-auth-provider-3tuw_aDK.js → email-auth-provider-wOISnCic.js} +7 -2
  13. package/dist/email-auth-provider-wOISnCic.js.map +1 -0
  14. package/dist/{guest-auth-provider-ClCOa69H.js → guest-auth-provider-Br3iM3O3.js} +2 -2
  15. package/dist/{guest-auth-provider-ClCOa69H.js.map → guest-auth-provider-Br3iM3O3.js.map} +1 -1
  16. package/dist/{guest-auth-provider-BwEXKnNK.mjs → guest-auth-provider-DyP5UUg6.mjs} +2 -2
  17. package/dist/{guest-auth-provider-CsM_SuGH.mjs.map → guest-auth-provider-DyP5UUg6.mjs.map} +1 -1
  18. package/dist/{guest-auth-provider-CsM_SuGH.mjs → guest-auth-provider-ZOBNFoeC.mjs} +2 -2
  19. package/dist/{guest-auth-provider-BwEXKnNK.mjs.map → guest-auth-provider-ZOBNFoeC.mjs.map} +1 -1
  20. package/dist/{guest-auth-provider-_jdqZKUo.js → guest-auth-provider-xap-VQBP.js} +2 -2
  21. package/dist/{guest-auth-provider-_jdqZKUo.js.map → guest-auth-provider-xap-VQBP.js.map} +1 -1
  22. package/dist/{index-B2HWEA13.js → index-B4_eKphx.js} +125 -59
  23. package/dist/index-B4_eKphx.js.map +1 -0
  24. package/dist/{index-q9BHoxbM.mjs → index-BaXUWG8Q.mjs} +126 -61
  25. package/dist/index-BaXUWG8Q.mjs.map +1 -0
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +5 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +2 -2
  30. package/dist/{index.native-CMNMw3Pe.js → index.native-B-pjNetI.js} +142 -60
  31. package/dist/index.native-B-pjNetI.js.map +1 -0
  32. package/dist/{index.native-DfDVa7MG.mjs → index.native-B4yI0BqT.mjs} +143 -62
  33. package/dist/index.native-B4yI0BqT.mjs.map +1 -0
  34. package/dist/index.native.js +1 -1
  35. package/dist/index.native.mjs +1 -1
  36. package/dist/{injected-evm-wallet-provider-AXc7Lmzk.mjs → injected-evm-wallet-provider-B4Kr6lnK.mjs} +2 -2
  37. package/dist/{injected-evm-wallet-provider-AXc7Lmzk.mjs.map → injected-evm-wallet-provider-B4Kr6lnK.mjs.map} +1 -1
  38. package/dist/{injected-evm-wallet-provider-qB_GQ9ih.js → injected-evm-wallet-provider-CKAv4Qxh.js} +2 -2
  39. package/dist/{injected-evm-wallet-provider-qB_GQ9ih.js.map → injected-evm-wallet-provider-CKAv4Qxh.js.map} +1 -1
  40. package/dist/{injected-evm-wallet-provider-CUNTCT-a.js → injected-evm-wallet-provider-DQMYqPus.js} +2 -2
  41. package/dist/{injected-evm-wallet-provider-CUNTCT-a.js.map → injected-evm-wallet-provider-DQMYqPus.js.map} +1 -1
  42. package/dist/{injected-evm-wallet-provider-E7eCpvLr.mjs → injected-evm-wallet-provider-Vw-Puwxh.mjs} +2 -2
  43. package/dist/{injected-evm-wallet-provider-E7eCpvLr.mjs.map → injected-evm-wallet-provider-Vw-Puwxh.mjs.map} +1 -1
  44. package/dist/{injected-wallet-provider-BEaDBzcd.js → injected-wallet-provider-B8QTPxf6.js} +14 -5
  45. package/dist/{injected-wallet-provider-BEaDBzcd.js.map → injected-wallet-provider-B8QTPxf6.js.map} +1 -1
  46. package/dist/{injected-wallet-provider-BqYJQDGu.js → injected-wallet-provider-BsTfBAD4.js} +14 -5
  47. package/dist/{injected-wallet-provider-BqYJQDGu.js.map → injected-wallet-provider-BsTfBAD4.js.map} +1 -1
  48. package/dist/{injected-wallet-provider-BoRoxrEl.mjs → injected-wallet-provider-CQxGVYja.mjs} +14 -5
  49. package/dist/{injected-wallet-provider-BoRoxrEl.mjs.map → injected-wallet-provider-CQxGVYja.mjs.map} +1 -1
  50. package/dist/{injected-wallet-provider-gmGZ254w.mjs → injected-wallet-provider-jj9dqm2Z.mjs} +14 -5
  51. package/dist/{injected-wallet-provider-gmGZ254w.mjs.map → injected-wallet-provider-jj9dqm2Z.mjs.map} +1 -1
  52. package/package.json +2 -2
  53. package/dist/email-auth-provider-3tuw_aDK.js.map +0 -1
  54. package/dist/email-auth-provider-C-SGTRZe.mjs.map +0 -1
  55. package/dist/email-auth-provider-C5bYKzpN.mjs.map +0 -1
  56. package/dist/email-auth-provider-CjbJ8wK1.js.map +0 -1
  57. package/dist/index-B2HWEA13.js.map +0 -1
  58. package/dist/index-q9BHoxbM.mjs.map +0 -1
  59. package/dist/index.native-CMNMw3Pe.js.map +0 -1
  60. package/dist/index.native-DfDVa7MG.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { getConfig, getActiveSessionManager, WebSessionManager, ReactNativeSessionManager, revokeSession, reconnectWithNewAuth, init as init$1, deriveUserIdentityFromIdToken, onSessionCleared, onSessionChange, subscribe, getFreshAuthToken, getSessionGeneration, getIdToken as getIdToken$1, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
1
+ import { getConfig, confirmSignature, getActiveSessionManager, WebSessionManager, ReactNativeSessionManager, revokeSession, reconnectWithNewAuth, init as init$1, deriveUserIdentityFromIdToken, onSessionCleared, onSessionChange, 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) {
@@ -35,7 +35,18 @@ function walletOperationGuard() {
35
35
  throw new Error('wallet_session_changed');
36
36
  };
37
37
  }
38
- function setWalletSessionState(key, state) { }
38
+ // This realm owns one active SDK session and one retained signer frame.
39
+ let activeWalletState;
40
+ function setWalletSessionState(key, state) { activeWalletState = { key, state }; }
41
+ function walletSessionState(key) {
42
+ if ((activeWalletState === null || activeWalletState === void 0 ? void 0 : activeWalletState.key) !== key)
43
+ return { status: 'verification-required' };
44
+ const state = activeWalletState.state;
45
+ if (state.status === 'ready' && (!Number.isFinite(state.expiresAt) || state.expiresAt <= Date.now())) {
46
+ return { status: 'verification-required', reason: 'wallet_session_expired' };
47
+ }
48
+ return state;
49
+ }
39
50
 
40
51
  /**
41
52
  * Platform abstraction layer for React Native compatibility.
@@ -226,6 +237,10 @@ class OffchainAuthProvider {
226
237
  async signTransaction(tx) {
227
238
  return this.wrappedProvider.signTransaction(tx);
228
239
  }
240
+ async prepareToSign() {
241
+ var _a, _b, _c;
242
+ return (_c = (await ((_b = (_a = this.wrappedProvider).prepareToSign) === null || _b === void 0 ? void 0 : _b.call(_a)))) !== null && _c !== void 0 ? _c : 'ready';
243
+ }
229
244
  /**
230
245
  * Sign and submit transaction - not supported in poofnet environment.
231
246
  * See the real providers (PhantomWalletProvider, SolanaKeypairProvider)
@@ -4143,6 +4158,11 @@ function detachWarmSignerIframe(origin) {
4143
4158
  detachIframe(modal);
4144
4159
  return true;
4145
4160
  }
4161
+ /** A removed frame cannot still supply its in-memory signing session. */
4162
+ function hasWarmSignerFrame(context) {
4163
+ var _a;
4164
+ return Boolean(((_a = modal === null || modal === void 0 ? void 0 : modal.iframe) === null || _a === void 0 ? void 0 : _a.isConnected) && modal.iframeContext === context);
4165
+ }
4146
4166
  function detachIframe(m) {
4147
4167
  if (m.iframe) {
4148
4168
  try {
@@ -4184,7 +4204,7 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
4184
4204
  const requestId = String(ex.request.requestId);
4185
4205
  // Serialize: the approve card is modal, and one warm frame handles one request at a time.
4186
4206
  const run = m.chain.then(() => new Promise((resolve, reject) => {
4187
- var _a;
4207
+ var _a, _b;
4188
4208
  let settled = false;
4189
4209
  let usedFallback = false;
4190
4210
  (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
@@ -4227,16 +4247,20 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
4227
4247
  /* frame gone */
4228
4248
  }
4229
4249
  };
4250
+ const dismiss = () => {
4251
+ if (!ex.silent)
4252
+ hideModal(m);
4253
+ };
4230
4254
  const goFallback = () => {
4231
4255
  if (usedFallback || settled)
4232
4256
  return;
4233
4257
  usedFallback = true;
4234
- hideModal(m);
4258
+ dismiss();
4235
4259
  finish(() => popupFallback().then(resolve, reject));
4236
4260
  };
4237
4261
  m.onBackdrop = () => {
4238
4262
  cancelInFrame();
4239
- hideModal(m);
4263
+ dismiss();
4240
4264
  finish(() => reject(new Error("cancelled")));
4241
4265
  };
4242
4266
  m.onIframeMessage = (d) => {
@@ -4251,17 +4275,18 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
4251
4275
  if (d.type === "bounded:turnkey:result" && d.requestId === requestId) {
4252
4276
  const outcome = ex.onResult(d);
4253
4277
  if ("error" in outcome) {
4254
- hideModal(m);
4278
+ dismiss();
4255
4279
  finish(() => reject(new Error(outcome.error)));
4256
4280
  return;
4257
4281
  }
4258
4282
  if (outcome.done) {
4259
- hideModal(m);
4283
+ dismiss();
4260
4284
  finish(() => resolve(outcome.value));
4261
4285
  }
4262
4286
  }
4263
4287
  };
4264
- showModal(m);
4288
+ if (!ex.silent)
4289
+ showModal(m);
4265
4290
  if (m.iframeReady)
4266
4291
  send();
4267
4292
  // If the frame never loads, degrade to the popup (best-effort - a post-load
@@ -4274,10 +4299,10 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
4274
4299
  ceilingTimer = window.setTimeout(() => {
4275
4300
  if (!settled) {
4276
4301
  cancelInFrame();
4277
- hideModal(m);
4302
+ dismiss();
4278
4303
  finish(() => reject(new Error("Wallet approval timed out.")));
4279
4304
  }
4280
- }, 5 * 60 * 1000);
4305
+ }, (_b = ex.ceilingMs) !== null && _b !== void 0 ? _b : 5 * 60 * 1000);
4281
4306
  }));
4282
4307
  m.chain = run.then(() => undefined, () => undefined);
4283
4308
  return run;
@@ -4779,6 +4804,59 @@ async function clearTurnkeySigningSession(idToken) {
4779
4804
  function hasTurnkeyWallet() {
4780
4805
  return activeTurnkeyAddress() !== null;
4781
4806
  }
4807
+ /** The signer frame could not take the exchange: it never loaded, or a page from before the request existed stays silent. */
4808
+ class SignerFrameUnavailable extends Error {
4809
+ constructor() { super('The Bounded signer frame did not answer.'); }
4810
+ }
4811
+ /** How long a silent session probe may wait for the frame before the write goes on without it. */
4812
+ const SESSION_PROBE_MS = 8000;
4813
+ /**
4814
+ * Make the wallet's 24-hour signing session live BEFORE a transaction exists. Without one the
4815
+ * approve card must first collect an emailed code, which takes longer than a transaction's
4816
+ * blockhash lifetime (about 33 seconds on mainnet in late 2026), so a transaction built before
4817
+ * the code is dead by the time it is signed. A live session is found with nothing shown: the
4818
+ * warm frame answers a silent probe, and it holds the session even where the browser blocks its
4819
+ * storage. Only a lapsed session opens the card, which runs the code ceremony and closes without
4820
+ * signing anything. Resolves `'established'` when that ceremony ran, else `'ready'`.
4821
+ *
4822
+ * Both exchanges run in the warm frame only, since it is the frame that signs next and a popup
4823
+ * keeps its session to itself. Where the frame cannot answer (an embedder that blocks it, or a
4824
+ * signer page from before this request existed), the write goes on the way it always did: the
4825
+ * approve card collects the code itself, and an expired build is built again.
4826
+ */
4827
+ async function ensureTurnkeySigningSession() {
4828
+ if (!hasDOM$2())
4829
+ throw new Error('Turnkey embedded-wallet signing is only available in the browser (trusted wallet UI).');
4830
+ const context = await turnkeySignerPage();
4831
+ context.assertCurrent();
4832
+ if (hasWarmSignerFrame(context.key) && walletSessionState(context.key).status === 'ready')
4833
+ return 'ready';
4834
+ const { url, origin } = context;
4835
+ const authorization = await fetchActionAuthorization('createWallet', context);
4836
+ const frameOnly = () => Promise.reject(new SignerFrameUnavailable());
4837
+ const exchange = (probeOnly) => ({
4838
+ context: context.key, assertCurrent: context.assertCurrent,
4839
+ request: Object.assign({ type: 'bounded:turnkey:session', requestId: `tksession_${Date.now()}_${++requestSeq}`, authorization }, (probeOnly ? { probeOnly: true } : {})),
4840
+ onResult: (d) => d.ok ? { done: true, value: d } : { error: String(d.error || 'The signing session could not be established') },
4841
+ });
4842
+ const probed = await runWidget(url, origin, Object.assign(Object.assign({}, exchange(true)), { silent: true, ceilingMs: SESSION_PROBE_MS }), frameOnly)
4843
+ .catch(() => null);
4844
+ if (!probed)
4845
+ return 'ready';
4846
+ let result = probed;
4847
+ if (result.ready !== true) {
4848
+ try {
4849
+ result = await runWidget(url, origin, exchange(false), frameOnly);
4850
+ }
4851
+ catch (error) {
4852
+ if (error instanceof SignerFrameUnavailable)
4853
+ return 'ready';
4854
+ throw error;
4855
+ }
4856
+ }
4857
+ setWalletSessionState(context.key, { status: 'ready', expiresAt: Number(result.signingSessionExpiresAt) });
4858
+ return result.established === true ? 'established' : 'ready';
4859
+ }
4782
4860
  /**
4783
4861
  * Open the Bounded Turnkey approval card and sign `message` (raw bytes) with the
4784
4862
  * user's Turnkey wallet, resolving with the ed25519 signature and wallet address.
@@ -4815,7 +4893,7 @@ async function signSolanaMessageViaTurnkey(message) {
4815
4893
  // A top-level popup keeps its signing session in the signer origin's own storage, which the
4816
4894
  // warm in-app frame (a partitioned context) cannot see, so it says nothing about that frame.
4817
4895
  if (transport !== 'popup')
4818
- setWalletSessionState(context.key, { expiresAt: Number(d.signingSessionExpiresAt) });
4896
+ setWalletSessionState(context.key, { status: 'ready', expiresAt: Number(d.signingSessionExpiresAt) });
4819
4897
  return { done: true, value: { signature: fromHex(d.signatureHex), address: d.address, subOrgId: String(d.subOrgId || '') } };
4820
4898
  }
4821
4899
  // The hosted signer refuses a cross-app signature inside a frame. Never retry it from here:
@@ -4895,10 +4973,9 @@ async function signAndSubmitTransactionWithTurnkey(transaction, feePayer) {
4895
4973
  // has signed silently invalidates their signature - signTransactionWithTurnkey only ADDS the
4896
4974
  // Turnkey signature, it never re-signs the others. So only refresh the blockhash while the
4897
4975
  // transaction is still unsigned; once a real signature is present, preserve the caller's message
4898
- // verbatim and confirm against the blockhash it already carries.
4899
- const hasSignature = transactionHasSignature$1(transaction);
4900
- let confirmBlockhash = blockhash;
4901
- if (!hasSignature) {
4976
+ // verbatim. The confirmation is fenced on the lifetime read above either way: for a pre-signed
4977
+ // transaction that is a superset of the one its signers fenced on, never a shorter wait.
4978
+ if (!transactionHasSignature$1(transaction)) {
4902
4979
  if (isLegacy) {
4903
4980
  const legacy = transaction;
4904
4981
  legacy.recentBlockhash = blockhash;
@@ -4914,19 +4991,17 @@ async function signAndSubmitTransactionWithTurnkey(transaction, feePayer) {
4914
4991
  transaction.message.recentBlockhash = blockhash;
4915
4992
  }
4916
4993
  }
4917
- else {
4918
- confirmBlockhash = (isLegacy
4919
- ? transaction.recentBlockhash
4920
- : transaction.message.recentBlockhash) || blockhash;
4921
- }
4922
4994
  const signed = await signTransactionWithTurnkey(transaction);
4923
4995
  const signature = await connection.sendRawTransaction(signed.serialize(), {
4924
4996
  skipPreflight: false,
4925
4997
  maxRetries: 3,
4926
4998
  });
4927
- const confirmation = await connection.confirmTransaction({ signature, blockhash: confirmBlockhash, lastValidBlockHeight }, 'confirmed');
4928
- if (confirmation.value.err) {
4929
- throw new Error(`Turnkey transaction failed: ${JSON.stringify(confirmation.value.err)}`);
4999
+ const confirmation = await confirmSignature(connection, { signature, lastValidBlockHeight });
5000
+ if (!confirmation.landed) {
5001
+ throw new Error(`Turnkey transaction ${signature} was not confirmed: ${confirmation.reason}. Check its status before sending it again.`);
5002
+ }
5003
+ if (confirmation.status.err) {
5004
+ throw new Error(`Turnkey transaction failed: ${JSON.stringify(confirmation.status.err)}`);
4930
5005
  }
4931
5006
  return signature;
4932
5007
  }
@@ -4934,6 +5009,7 @@ async function signAndSubmitTransactionWithTurnkey(transaction, feePayer) {
4934
5009
  var turnkeySignerBridge = /*#__PURE__*/Object.freeze({
4935
5010
  __proto__: null,
4936
5011
  clearTurnkeySigningSession: clearTurnkeySigningSession,
5012
+ ensureTurnkeySigningSession: ensureTurnkeySigningSession,
4937
5013
  hasTurnkeyWallet: hasTurnkeyWallet,
4938
5014
  signAndSubmitTransactionWithTurnkey: signAndSubmitTransactionWithTurnkey,
4939
5015
  signMessageWithTurnkey: signMessageWithTurnkey,
@@ -5013,6 +5089,11 @@ const oidcProviderSingleton = {
5013
5089
  throw new Error(OIDC_NO_WALLET);
5014
5090
  return signTransactionV1WithTurnkey(transaction);
5015
5091
  },
5092
+ async prepareToSign() {
5093
+ if (!hasTurnkeyWallet())
5094
+ throw new Error(OIDC_NO_WALLET);
5095
+ return ensureTurnkeySigningSession();
5096
+ },
5016
5097
  supportedTransactionVersions() {
5017
5098
  return hasTurnkeyWallet() ? ['legacy', 0, 1] : ['legacy', 0];
5018
5099
  },
@@ -6068,7 +6149,7 @@ async function getAuthProvider(config, fromStorage = false) {
6068
6149
  // manager as legacy email sessions. Human login should be started
6069
6150
  // with loginWithRedirect(); this provider is kept as the restore and
6070
6151
  // logout surface for those sessions.
6071
- currentAuthProvider = new (await import('./email-auth-provider-C5bYKzpN.mjs')).EmailAuthProvider();
6152
+ currentAuthProvider = new (await import('./email-auth-provider-DOI-4lPC.mjs')).EmailAuthProvider();
6072
6153
  break;
6073
6154
  case "phantom": {
6074
6155
  // First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
@@ -6110,7 +6191,7 @@ async function getAuthProvider(config, fromStorage = false) {
6110
6191
  // (bounded-login-widget.ts), so registration never counts as
6111
6192
  // evidence the user has a wallet.
6112
6193
  await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
6113
- const { InjectedWalletProvider } = await import('./injected-wallet-provider-BoRoxrEl.mjs');
6194
+ const { InjectedWalletProvider } = await import('./injected-wallet-provider-CQxGVYja.mjs');
6114
6195
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
6115
6196
  break;
6116
6197
  }
@@ -6123,7 +6204,7 @@ async function getAuthProvider(config, fromStorage = false) {
6123
6204
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
6124
6205
  // to point at a specific wallet or set chainId/domain.
6125
6206
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
6126
- const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-E7eCpvLr.mjs');
6207
+ const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-Vw-Puwxh.mjs');
6127
6208
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
6128
6209
  break;
6129
6210
  }
@@ -6148,7 +6229,7 @@ async function getAuthProvider(config, fromStorage = false) {
6148
6229
  break;
6149
6230
  case "guest":
6150
6231
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
6151
- currentAuthProvider = new (await import('./guest-auth-provider-CsM_SuGH.mjs')).GuestAuthProvider();
6232
+ currentAuthProvider = new (await import('./guest-auth-provider-ZOBNFoeC.mjs')).GuestAuthProvider();
6152
6233
  break;
6153
6234
  }
6154
6235
  if (!currentAuthProvider) {
@@ -6210,7 +6291,7 @@ async function signInAnonymously() {
6210
6291
  // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
6211
6292
  // the main bundle for data-only apps. Specifier is a static string literal
6212
6293
  // so bundle-splitting can see it.
6213
- const provider = new (await import('./guest-auth-provider-CsM_SuGH.mjs')).GuestAuthProvider();
6294
+ const provider = new (await import('./guest-auth-provider-ZOBNFoeC.mjs')).GuestAuthProvider();
6214
6295
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
6215
6296
  // adoptSessionProvider awaits only getConfig() (already resolved here) and then
6216
6297
  // runs every write - provider/method/config/marker/user - in one synchronous
@@ -6381,7 +6462,7 @@ function ensureSharedWalletLoginReady() {
6381
6462
  if (!sharedWalletReady) {
6382
6463
  sharedWalletReady = (async () => {
6383
6464
  await getConfig();
6384
- await import('./injected-wallet-provider-BoRoxrEl.mjs');
6465
+ await import('./injected-wallet-provider-CQxGVYja.mjs');
6385
6466
  })().catch((error) => {
6386
6467
  sharedWalletReady = null;
6387
6468
  throw error;
@@ -8561,35 +8642,29 @@ async function getParsedTransactionCompat(connection, signature) {
8561
8642
  }
8562
8643
  }
8563
8644
  /**
8564
- * Polls getSignatureStatuses until the transaction is confirmed, then checks for errors.
8565
- * Throws if the transaction failed on-chain. Returns parsed transaction info on success.
8645
+ * Waits for a broadcast signature by HTTPS status polling, fenced on the blockhash
8646
+ * lifetime it was signed against (core's `confirmSignature`), then checks for an
8647
+ * on-chain error. Throws if the transaction failed on-chain or was not seen before
8648
+ * the fence closed. Returns parsed transaction info on success.
8566
8649
  */
8567
- async function confirmAndCheckTransaction(connection, signature) {
8650
+ async function confirmAndCheckTransaction(connection, signature, lastValidBlockHeight) {
8568
8651
  var _a;
8569
- const maxAttempts = 15;
8570
- for (let i = 0; i < maxAttempts; i++) {
8571
- const { value } = await connection.getSignatureStatuses([signature]);
8572
- const status = value[0];
8573
- if (status) {
8574
- if (status.err) {
8575
- let logMessages;
8576
- try {
8577
- const txInfo = await getParsedTransactionCompat(connection, signature);
8578
- logMessages = (_a = txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta) === null || _a === void 0 ? void 0 : _a.logMessages;
8579
- }
8580
- catch (_b) {
8581
- // Log retrieval is diagnostic only; the on-chain error is the verdict.
8582
- }
8583
- const errorMessage = extractTransactionError(status.err, logMessages);
8584
- throw new Error(`Transaction failed: ${errorMessage}`);
8585
- }
8586
- if (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized') {
8587
- return await getParsedTransactionCompat(connection, signature);
8588
- }
8652
+ const confirmation = await confirmSignature(connection, { signature, lastValidBlockHeight });
8653
+ if (!confirmation.landed) {
8654
+ throw new Error(`Transaction ${signature} was not confirmed: ${confirmation.reason}. Check its status before sending it again.`);
8655
+ }
8656
+ if (confirmation.status.err) {
8657
+ let logMessages;
8658
+ try {
8659
+ const txInfo = await getParsedTransactionCompat(connection, signature);
8660
+ logMessages = (_a = txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta) === null || _a === void 0 ? void 0 : _a.logMessages;
8589
8661
  }
8590
- await new Promise(resolve => setTimeout(resolve, 1000));
8662
+ catch (_b) {
8663
+ // Log retrieval is diagnostic only; the on-chain error is the verdict.
8664
+ }
8665
+ throw new Error(`Transaction failed: ${extractTransactionError(confirmation.status.err, logMessages)}`);
8591
8666
  }
8592
- throw new Error('Transaction confirmation timeout');
8667
+ return getParsedTransactionCompat(connection, signature);
8593
8668
  }
8594
8669
 
8595
8670
  /**
@@ -8759,24 +8834,30 @@ class PrivyExpoProvider {
8759
8834
  // included), so refreshing the blockhash after any signer (sponsor / co-signer)
8760
8835
  // has signed silently invalidates their signature. Only refresh while the
8761
8836
  // transaction is still unsigned; once a real signature is present, submit the
8762
- // caller's transaction verbatim.
8837
+ // caller's transaction verbatim. Either way the confirmation is fenced on a
8838
+ // lifetime read now: for a pre-signed transaction that is a superset of the
8839
+ // one its signers fenced on, never a shorter wait.
8840
+ let lastValidBlockHeight;
8763
8841
  if (!transactionHasSignature(transaction)) {
8842
+ const { blockhash, lastValidBlockHeight: freshLastValid } = await connection.getLatestBlockhash('confirmed');
8843
+ lastValidBlockHeight = freshLastValid;
8764
8844
  const isLegacyTx = 'recentBlockhash' in transaction &&
8765
8845
  !('message' in transaction && 'staticAccountKeys' in transaction.message);
8766
8846
  if (isLegacyTx) {
8767
8847
  const legacyTx = transaction;
8768
- const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
8769
8848
  legacyTx.recentBlockhash = blockhash;
8770
8849
  legacyTx.lastValidBlockHeight = lastValidBlockHeight;
8771
8850
  legacyTx.feePayer = feePayer || new PublicKey(wallet.address);
8772
8851
  }
8773
8852
  else {
8774
8853
  const versionedTx = transaction;
8775
- const { blockhash } = await connection.getLatestBlockhash('confirmed');
8776
8854
  versionedTx.message.recentBlockhash = blockhash;
8777
8855
  }
8778
8856
  }
8779
- const { signature } = await this.signAndSubmitInternal(transaction, wallet, connection);
8857
+ else {
8858
+ ({ lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed'));
8859
+ }
8860
+ const { signature } = await this.signAndSubmitInternal(transaction, wallet, connection, lastValidBlockHeight);
8780
8861
  return signature;
8781
8862
  }
8782
8863
  async restoreSession(beforeCommit) {
@@ -8847,11 +8928,11 @@ class PrivyExpoProvider {
8847
8928
  `Sign in again before ${action}.`);
8848
8929
  }
8849
8930
  }
8850
- async signAndSubmitInternal(transaction, wallet, connection) {
8931
+ async signAndSubmitInternal(transaction, wallet, connection, lastValidBlockHeight) {
8851
8932
  // Use Privy's combined sign+send
8852
8933
  const result = await wallet.signAndSendTransaction(transaction, connection);
8853
8934
  const signature = result.signature;
8854
- const txInfo = await confirmAndCheckTransaction(connection, signature);
8935
+ const txInfo = await confirmAndCheckTransaction(connection, signature, lastValidBlockHeight);
8855
8936
  return { signature, txInfo };
8856
8937
  }
8857
8938
  // The constructor rpcUrl wins, then init()'s rpcUrl, then the platform RPC
@@ -8887,5 +8968,5 @@ class PrivyExpoProvider {
8887
8968
  }
8888
8969
  }
8889
8970
 
8890
- export { PARK_REASONS as $, waitForAuthReady as A, login as B, logout as C, getAuthProvider as D, signInAnonymously as E, loginWithPrivy as F, loginWithRedirect as G, completeLoginFromRedirect as H, getLoginReturnError as I, loginWithPopup as J, useAuth as K, useQuery as L, useBuildRun as M, apps as N, getIdToken as O, onramp as P, onrampQuote as Q, onrampStatus as R, setPlatform as S, OffchainAuthProvider as T, PrivyExpoProvider as U, builds as V, BuildsApiError as W, mediaAgentTools as X, NON_TERMINAL_STATES as Y, TERMINAL_STATES as Z, RUN_STATES as _, signMessageWithTurnkey as a, FAILURE_REASONS as a0, BUILD_REVIEW_CAPABILITY_SCHEMA as a1, BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as a2, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as a3, signTransactionWithTurnkey as b, signTransactionV1WithTurnkey as c, signAndSubmitTransactionWithTurnkey as d, bs58 as e, getWallets as f, getPlatform as g, hasTurnkeyWallet as h, solanaMobileWalletLeavesPage as i, solanaMobileWalletAnswersSignInFromCache as j, isSolanaMobileWallet as k, setAuthLoading as l, bufferExports as m, normalizeSolanaRpcUrl as n, setStoredAuthMethod as o, confirmAndCheckTransaction as p, resolveSolanaRpcUrl as q, resolveSolanaWalletStandardChain as r, setCurrentUser as s, transactionHasSignature as t, init as u, getCurrentUser as v, walletStandardFeatureName as w, onAuthStateChanged as x, onAuthLoadingChanged as y, getAuthLoading as z };
8891
- //# sourceMappingURL=index.native-DfDVa7MG.mjs.map
8971
+ export { RUN_STATES as $, getAuthLoading as A, waitForAuthReady as B, login as C, logout as D, getAuthProvider as E, signInAnonymously as F, loginWithPrivy as G, loginWithRedirect as H, completeLoginFromRedirect as I, getLoginReturnError as J, loginWithPopup as K, useAuth as L, useQuery as M, useBuildRun as N, apps as O, getIdToken as P, onramp as Q, onrampQuote as R, onrampStatus as S, setPlatform as T, OffchainAuthProvider as U, PrivyExpoProvider as V, builds as W, BuildsApiError as X, mediaAgentTools as Y, NON_TERMINAL_STATES as Z, TERMINAL_STATES as _, signMessageWithTurnkey as a, PARK_REASONS as a0, FAILURE_REASONS as a1, BUILD_REVIEW_CAPABILITY_SCHEMA as a2, BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as a3, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as a4, signTransactionWithTurnkey as b, signTransactionV1WithTurnkey as c, signAndSubmitTransactionWithTurnkey as d, ensureTurnkeySigningSession as e, bs58 as f, getPlatform as g, hasTurnkeyWallet as h, getWallets as i, solanaMobileWalletLeavesPage as j, solanaMobileWalletAnswersSignInFromCache as k, isSolanaMobileWallet as l, setAuthLoading as m, normalizeSolanaRpcUrl as n, bufferExports as o, setStoredAuthMethod as p, confirmAndCheckTransaction as q, resolveSolanaWalletStandardChain as r, setCurrentUser as s, transactionHasSignature as t, resolveSolanaRpcUrl as u, init as v, walletStandardFeatureName as w, getCurrentUser as x, onAuthStateChanged as y, onAuthLoadingChanged as z };
8972
+ //# sourceMappingURL=index.native-B4yI0BqT.mjs.map