@bounded-sh/client 0.0.114 → 0.0.115

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 (58) hide show
  1. package/dist/auth/providers/injected-wallet-types.d.ts +11 -2
  2. package/dist/auth/providers/wallet-standard-discovery.d.ts +2 -0
  3. package/dist/auth/turnkey-signer-window.d.ts +19 -0
  4. package/dist/auth/turnkey-signing-capability.d.ts +5 -1
  5. package/dist/{email-auth-provider-nDZjRDpj.mjs → email-auth-provider-ByNBWdfi.mjs} +2 -2
  6. package/dist/{email-auth-provider-Bk5GSpYT.mjs.map → email-auth-provider-ByNBWdfi.mjs.map} +1 -1
  7. package/dist/{email-auth-provider-Bk5GSpYT.mjs → email-auth-provider-CODHCC3h.mjs} +2 -2
  8. package/dist/{email-auth-provider-nDZjRDpj.mjs.map → email-auth-provider-CODHCC3h.mjs.map} +1 -1
  9. package/dist/{email-auth-provider-DeORQbTK.js → email-auth-provider-CPHrcy_b.js} +2 -2
  10. package/dist/{email-auth-provider-DeORQbTK.js.map → email-auth-provider-CPHrcy_b.js.map} +1 -1
  11. package/dist/{email-auth-provider-Cr66GaKw.js → email-auth-provider-CwG04f4u.js} +2 -2
  12. package/dist/{email-auth-provider-Cr66GaKw.js.map → email-auth-provider-CwG04f4u.js.map} +1 -1
  13. package/dist/{guest-auth-provider-CUNkZVFK.js → guest-auth-provider-3rfSwq3f.js} +2 -2
  14. package/dist/{guest-auth-provider-CUNkZVFK.js.map → guest-auth-provider-3rfSwq3f.js.map} +1 -1
  15. package/dist/{guest-auth-provider-ejUTbjCC.mjs → guest-auth-provider-CGN4k_LG.mjs} +2 -2
  16. package/dist/{guest-auth-provider-DDudqqxY.mjs.map → guest-auth-provider-CGN4k_LG.mjs.map} +1 -1
  17. package/dist/{guest-auth-provider-DDudqqxY.mjs → guest-auth-provider-PfOp_Yzj.mjs} +2 -2
  18. package/dist/{guest-auth-provider-ejUTbjCC.mjs.map → guest-auth-provider-PfOp_Yzj.mjs.map} +1 -1
  19. package/dist/{guest-auth-provider-5bX-xt6K.js → guest-auth-provider-d6dk97x6.js} +2 -2
  20. package/dist/{guest-auth-provider-5bX-xt6K.js.map → guest-auth-provider-d6dk97x6.js.map} +1 -1
  21. package/dist/{index-BAiLpNEQ.mjs → index-C63ceG_z.mjs} +789 -73
  22. package/dist/index-C63ceG_z.mjs.map +1 -0
  23. package/dist/{index-BZ0X1Z9X.js → index-nU0ZSfWs.js} +793 -71
  24. package/dist/index-nU0ZSfWs.js.map +1 -0
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.js +6 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/{index.native-DJSOqyKQ.js → index.native-BBLBnqal.js} +75 -22
  30. package/dist/index.native-BBLBnqal.js.map +1 -0
  31. package/dist/{index.native-DcW2klyn.mjs → index.native-DLAEWwuZ.mjs} +76 -23
  32. package/dist/index.native-DLAEWwuZ.mjs.map +1 -0
  33. package/dist/index.native.js +1 -1
  34. package/dist/index.native.mjs +1 -1
  35. package/dist/{injected-evm-wallet-provider-C4aKa2v1.mjs → injected-evm-wallet-provider-C4vNOS4P.mjs} +2 -2
  36. package/dist/{injected-evm-wallet-provider-C4aKa2v1.mjs.map → injected-evm-wallet-provider-C4vNOS4P.mjs.map} +1 -1
  37. package/dist/{injected-evm-wallet-provider-BDYWjIOQ.js → injected-evm-wallet-provider-C6KC7pJ6.js} +2 -2
  38. package/dist/{injected-evm-wallet-provider-BDYWjIOQ.js.map → injected-evm-wallet-provider-C6KC7pJ6.js.map} +1 -1
  39. package/dist/{injected-evm-wallet-provider-D06arDQD.js → injected-evm-wallet-provider-D1JA3cL4.js} +2 -2
  40. package/dist/{injected-evm-wallet-provider-D06arDQD.js.map → injected-evm-wallet-provider-D1JA3cL4.js.map} +1 -1
  41. package/dist/{injected-evm-wallet-provider-BQ_kG1vI.mjs → injected-evm-wallet-provider-D7rOyYdr.mjs} +2 -2
  42. package/dist/{injected-evm-wallet-provider-BQ_kG1vI.mjs.map → injected-evm-wallet-provider-D7rOyYdr.mjs.map} +1 -1
  43. package/dist/{injected-wallet-provider-Dj-F69gb.mjs → injected-wallet-provider-BLRrB2rb.mjs} +11 -5
  44. package/dist/{injected-wallet-provider-Dj-F69gb.mjs.map → injected-wallet-provider-BLRrB2rb.mjs.map} +1 -1
  45. package/dist/{injected-wallet-provider-B9jvzDM5.js → injected-wallet-provider-BXFicWTx.js} +11 -5
  46. package/dist/{injected-wallet-provider-B9jvzDM5.js.map → injected-wallet-provider-BXFicWTx.js.map} +1 -1
  47. package/dist/{injected-wallet-provider-Dqmk-m4V.js → injected-wallet-provider-BvlKZoVJ.js} +59 -34
  48. package/dist/injected-wallet-provider-BvlKZoVJ.js.map +1 -0
  49. package/dist/{injected-wallet-provider-DxPcYxP-.mjs → injected-wallet-provider-DruiX7GK.mjs} +59 -34
  50. package/dist/injected-wallet-provider-DruiX7GK.mjs.map +1 -0
  51. package/dist/venue-escrow.d.ts +113 -0
  52. package/package.json +2 -2
  53. package/dist/index-BAiLpNEQ.mjs.map +0 -1
  54. package/dist/index-BZ0X1Z9X.js.map +0 -1
  55. package/dist/index.native-DJSOqyKQ.js.map +0 -1
  56. package/dist/index.native-DcW2klyn.mjs.map +0 -1
  57. package/dist/injected-wallet-provider-Dqmk-m4V.js.map +0 -1
  58. package/dist/injected-wallet-provider-DxPcYxP-.mjs.map +0 -1
@@ -615,6 +615,37 @@ class OffchainAuthProvider {
615
615
  }
616
616
  }
617
617
 
618
+ const SELECTED_WALLET_UNAVAILABLE_ERR = 'The selected Solana wallet is unavailable. Select it again before continuing.';
619
+ /** Check login capabilities without connecting, signing, or loading a wallet SDK.
620
+ * This checks login only; it does not promise message or transaction signing. */
621
+ function supportsWalletSignIn(provider) {
622
+ if (typeof provider !== 'object' || provider === null)
623
+ return false;
624
+ const wallet = provider;
625
+ return typeof wallet.connect === 'function' && typeof wallet.signIn === 'function';
626
+ }
627
+ /**
628
+ * Default provider discovery: Phantom-first, then any Wallet-Standard
629
+ * `window.solana`. Kept tiny + synchronous (no heavy imports) so it works inside
630
+ * a user gesture and can be eagerly exported from the SDK entry. This names the
631
+ * default wallet even when it cannot sign in: login must refuse that wallet,
632
+ * never silently replace it with a different identity. Custom pickers can use
633
+ * supportsWalletSignIn() to decide which providers to offer for login.
634
+ */
635
+ function defaultInjectedProvider() {
636
+ var _a;
637
+ if (typeof window === 'undefined')
638
+ return null;
639
+ const w = window;
640
+ const phantom = (_a = w === null || w === void 0 ? void 0 : w.phantom) === null || _a === void 0 ? void 0 : _a.solana;
641
+ if (phantom && typeof phantom.signMessage === 'function')
642
+ return phantom;
643
+ const generic = w === null || w === void 0 ? void 0 : w.solana;
644
+ if (generic && typeof generic.signMessage === 'function')
645
+ return generic;
646
+ return null;
647
+ }
648
+
618
649
  // issuer-logout-bounce.ts - commit the top-level navigation that ends the hosted
619
650
  // issuer's browser session (the Better Auth cookie on auth.bounded.sh).
620
651
  //
@@ -4554,6 +4585,108 @@ async function openHiddenSignerFrame(page) {
4554
4585
  };
4555
4586
  }
4556
4587
 
4588
+ // turnkey-signer-window.ts - the top-level Bounded signer window: opening it, and reserving it
4589
+ // inside a click for an approval that is reached only after awaits.
4590
+ //
4591
+ // A cross-app Turnkey signature (the capability says `transport: 'popup'`) cannot run in the
4592
+ // in-app frame, so it opens in its own window, and a browser opens a window only inside the
4593
+ // user's click. The click handler therefore calls `reserveSignerPopup()` first, before any
4594
+ // `await`, and the exchange in turnkey-signer-bridge.ts navigates that window to the signer later.
4595
+ //
4596
+ // Kept out of the bridge on purpose: the bridge is loaded lazily as a whole module, so a bundler
4597
+ // keeps every one of its exports in every app that signs, while this reservation is needed only
4598
+ // by an app that funds an escrow.
4599
+ function openSignerWindow(url, w = 420, h = 620) {
4600
+ const left = window.screenX + Math.max(0, (window.outerWidth - w) / 2);
4601
+ const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
4602
+ return window.open(url, 'bounded-turnkey-signer', `width=${w},height=${h},left=${left},top=${top}`);
4603
+ }
4604
+ // One slot: the next popup exchange takes it, and a new reservation replaces an unused earlier one.
4605
+ // A property of a const rather than a reassigned `let`, which a bundler would keep every assignment
4606
+ // to, dragging the reservation into apps that never reserve.
4607
+ const reserved = { popup: null };
4608
+ /** Write `text` into the window; false when the window is not ours to write (it still works: it is navigated to the signer next). */
4609
+ function paint(popup, text) {
4610
+ try {
4611
+ const { document: doc } = popup;
4612
+ doc.title = 'Bounded';
4613
+ doc.documentElement.style.colorScheme = 'light dark';
4614
+ doc.body.style.cssText = 'margin:0;padding:24px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;min-height:100vh;text-align:center;font:15px system-ui,sans-serif;background:Canvas;color:CanvasText';
4615
+ doc.body.textContent = text;
4616
+ return true;
4617
+ }
4618
+ catch (_a) {
4619
+ return false;
4620
+ }
4621
+ }
4622
+ /**
4623
+ * Open the signer window NOW, synchronously, showing a neutral "Preparing your approval..."
4624
+ * page (a blank document with local text, no remote content). Call it from a user gesture,
4625
+ * before any `await`, and `release()` it when the flow ends. A cross-app Turnkey signature
4626
+ * then runs in this window instead of needing a fresh gesture.
4627
+ * Returns null when there is no DOM or the browser blocked the window.
4628
+ */
4629
+ function reserveSignerPopup() {
4630
+ var _a;
4631
+ if (typeof window === 'undefined' || typeof document === 'undefined')
4632
+ return null;
4633
+ try {
4634
+ (_a = reserved.popup) === null || _a === void 0 ? void 0 : _a.close();
4635
+ }
4636
+ catch ( /* already closed */_b) { /* already closed */ }
4637
+ let popup = null;
4638
+ try {
4639
+ popup = openSignerWindow('');
4640
+ }
4641
+ catch ( /* a sandboxed page may throw instead of returning null */_c) { /* a sandboxed page may throw instead of returning null */ }
4642
+ reserved.popup = popup;
4643
+ if (!popup)
4644
+ return null;
4645
+ paint(popup, 'Preparing your approval...');
4646
+ return {
4647
+ release(message) {
4648
+ const unused = reserved.popup === popup;
4649
+ if (unused)
4650
+ reserved.popup = null;
4651
+ try {
4652
+ if (!message || !unused || popup.closed)
4653
+ return popup.close();
4654
+ const text = message.slice(0, 160);
4655
+ if (!paint(popup, text))
4656
+ return popup.close(); // not a window of ours to write on, so no message to linger on
4657
+ // Close it only while it still shows this text: a window that was reserved again or sent on to
4658
+ // the signer in the meantime is no longer ours to close.
4659
+ setTimeout(() => { try {
4660
+ if (popup.document.body.textContent === text)
4661
+ popup.close();
4662
+ }
4663
+ catch ( /* sent on to the signer */_a) { /* sent on to the signer */ } }, 1500);
4664
+ }
4665
+ catch ( /* already closed */_a) { /* already closed */ }
4666
+ },
4667
+ };
4668
+ }
4669
+ /** Hand the reserved window, if one is held, to an exchange: navigated to the signer page at `url`. */
4670
+ function takeReservedPopup(url) {
4671
+ const popup = reserved.popup;
4672
+ reserved.popup = null;
4673
+ if (!popup)
4674
+ return null;
4675
+ if (popup.closed)
4676
+ throw new Error('Wallet approval window was closed before it completed.');
4677
+ try {
4678
+ popup.location.replace(url);
4679
+ }
4680
+ catch (_a) {
4681
+ try {
4682
+ popup.close();
4683
+ }
4684
+ catch ( /* ignore */_b) { /* ignore */ }
4685
+ throw new Error('Wallet approval window could not open the signer - retry from a click.');
4686
+ }
4687
+ return popup;
4688
+ }
4689
+
4557
4690
  // turnkey-signing-capability.ts - the pure AS-02 (DS2-0112) signing-capability logic,
4558
4691
  // kept import-free (no DOM, no session, no @bounded-sh/core) so it is unit-testable.
4559
4692
  //
@@ -4565,9 +4698,10 @@ async function openHiddenSignerFrame(page) {
4565
4698
  // so a regression here (a dropped capability, a wrong route, a swallowed error) is
4566
4699
  // caught without a browser.
4567
4700
  // POST the Bounded id token + payload hash to the issuer's capability mint route and
4568
- // return the issuer-signed capability for exactly these bytes. Credential-free: identity
4569
- // is proven with the id token in the body (not an ambient cookie the cross-origin fetch
4570
- // would not carry). Throws with the same stable messages the bridge relied on inline.
4701
+ // return the issuer-signed capability for exactly these bytes, with the transport the
4702
+ // issuer requires for them. Credential-free: identity is proven with the id token in the
4703
+ // body (not an ambient cookie the cross-origin fetch would not carry). Throws with the same
4704
+ // stable messages the bridge relied on inline.
4571
4705
  async function requestTurnkeySigningCapability(opts) {
4572
4706
  const base = opts.baseUrl.replace(/\/$/, '');
4573
4707
  let res;
@@ -4597,7 +4731,7 @@ async function requestTurnkeySigningCapability(opts) {
4597
4731
  if (!d || typeof d.capability !== 'string' || !d.capability) {
4598
4732
  throw new Error('Turnkey signing capability was malformed.');
4599
4733
  }
4600
- return d.capability;
4734
+ return d.transport === 'popup' ? { capability: d.capability, transport: 'popup' } : { capability: d.capability };
4601
4735
  }
4602
4736
  // Assemble the `bounded:turnkey:sign` postMessage request, carrying the issuer-signed
4603
4737
  // capability for the same bytes. Without the capability the hosted signer refuses
@@ -4688,12 +4822,16 @@ function hasDOM$3() {
4688
4822
  // when we cannot embed (no DOM, or the frame never mounts/loads). Nothing in the
4689
4823
  // email-session flow needs a popup by preference: the code entry and the approval
4690
4824
  // click both run fine inside a cross-origin iframe on every engine (the old
4691
- // Safari popup preference existed only for in-iframe WebAuthn CREATE).
4825
+ // Safari popup preference existed only for in-iframe WebAuthn CREATE). The one
4826
+ // exception is a signature the issuer marks `transport: 'popup'` (a cross-app
4827
+ // write): the hosted signer refuses it inside any frame, so it never touches the widget.
4692
4828
  async function deliver(url, origin, ex) {
4693
4829
  var _a, _b;
4694
4830
  const popup = () => runPopup(url, origin, ex);
4695
4831
  (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
4696
- const result = await runWidget(url, origin, { request: ex.request, onResult: ex.onResult, context: ex.context, assertCurrent: ex.assertCurrent }, popup);
4832
+ const result = ex.transport === 'popup'
4833
+ ? await popup()
4834
+ : await runWidget(url, origin, { request: ex.request, onResult: ex.onResult, context: ex.context, assertCurrent: ex.assertCurrent }, popup);
4697
4835
  (_b = ex.assertCurrent) === null || _b === void 0 ? void 0 : _b.call(ex);
4698
4836
  return result;
4699
4837
  }
@@ -4765,14 +4903,12 @@ function activeTurnkeyAddress() {
4765
4903
  : null;
4766
4904
  }
4767
4905
  let requestSeq = 0;
4768
- // Shared popup driver: open the signer page, do the ready/postMessage handshake, and
4769
- // resolve when `onResult` accepts a result message. Origin + source are pinned.
4906
+ // Shared popup driver: open the signer page (in the reserved window when one is held), do the
4907
+ // ready/postMessage handshake, and resolve when `onResult` accepts a result message. Origin +
4908
+ // source are pinned.
4770
4909
  async function runPopup(url, signerOrigin, ex) {
4771
- var _a, _b;
4772
- const w = (_a = ex.width) !== null && _a !== void 0 ? _a : 420, h = (_b = ex.height) !== null && _b !== void 0 ? _b : 620;
4773
- const left = window.screenX + Math.max(0, (window.outerWidth - w) / 2);
4774
- const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
4775
- const popup = window.open(url, 'bounded-turnkey-signer', `width=${w},height=${h},left=${left},top=${top}`);
4910
+ var _a;
4911
+ const popup = (_a = takeReservedPopup(url)) !== null && _a !== void 0 ? _a : openSignerWindow(url, ex.width, ex.height);
4776
4912
  if (!popup) {
4777
4913
  throw new Error('Popup blocked - call this from a user gesture (e.g. a click handler) so the wallet approval window can open.');
4778
4914
  }
@@ -5022,7 +5158,7 @@ async function signSolanaMessageViaTurnkey(message) {
5022
5158
  const messageHex = toHex(message);
5023
5159
  // AS-02: obtain the issuer-signed capability for THESE exact bytes first; the signer will
5024
5160
  // refuse (capability_required) without it. Fetched per signature (each is single-payload).
5025
- const capability = await fetchSigningCapability(messageHex, context);
5161
+ const { capability, transport } = await fetchSigningCapability(messageHex, context);
5026
5162
  // Inline (authMode:"turnkey") sessions plant no Better Auth cookie on the issuer, so the
5027
5163
  // signer's same-origin status/create fetches need a bearer session proof: attach the
5028
5164
  // createWallet action authorization (it covers the sign flow's get-or-create too). Minted
@@ -5031,11 +5167,20 @@ async function signSolanaMessageViaTurnkey(message) {
5031
5167
  return await deliver(url, origin, {
5032
5168
  context: context.key, assertCurrent: context.assertCurrent,
5033
5169
  request: buildTurnkeySignRequest({ requestId, messageHex, capability, authorization }),
5170
+ transport,
5034
5171
  onResult: (d) => {
5035
5172
  if (d.ok && typeof d.signatureHex === 'string' && typeof d.address === 'string') {
5036
- setWalletSessionState(context.key, { status: 'ready', expiresAt: Number(d.signingSessionExpiresAt) });
5173
+ // A top-level popup keeps its signing session in the signer origin's own storage, which the
5174
+ // warm in-app frame (a partitioned context) cannot see, so it says nothing about that frame.
5175
+ if (transport !== 'popup')
5176
+ setWalletSessionState(context.key, { status: 'ready', expiresAt: Number(d.signingSessionExpiresAt) });
5037
5177
  return { done: true, value: { signature: fromHex(d.signatureHex), address: d.address, subOrgId: String(d.subOrgId || '') } };
5038
5178
  }
5179
+ // The hosted signer refuses a cross-app signature inside a frame. Never retry it from here:
5180
+ // the top-level window needs the user's own click.
5181
+ if (d.error === 'top_level_required') {
5182
+ return { error: 'top_level_required: an approval that writes to another app must open in its own window. Start it from a click handler.' };
5183
+ }
5039
5184
  return { error: String(d.error || 'Turnkey signing failed') };
5040
5185
  },
5041
5186
  });
@@ -6351,7 +6496,7 @@ async function getAuthProvider(config, fromStorage = false) {
6351
6496
  // manager as legacy email sessions. Human login should be started
6352
6497
  // with loginWithRedirect(); this provider is kept as the restore and
6353
6498
  // logout surface for those sessions.
6354
- currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-DeORQbTK.js'); })).EmailAuthProvider();
6499
+ currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-CPHrcy_b.js'); })).EmailAuthProvider();
6355
6500
  break;
6356
6501
  case "phantom": {
6357
6502
  // First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
@@ -6393,7 +6538,7 @@ async function getAuthProvider(config, fromStorage = false) {
6393
6538
  // (bounded-login-widget.ts), so registration never counts as
6394
6539
  // evidence the user has a wallet.
6395
6540
  await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
6396
- const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
6541
+ const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-BXFicWTx.js'); });
6397
6542
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
6398
6543
  break;
6399
6544
  }
@@ -6406,7 +6551,7 @@ async function getAuthProvider(config, fromStorage = false) {
6406
6551
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
6407
6552
  // to point at a specific wallet or set chainId/domain.
6408
6553
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
6409
- const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-D06arDQD.js'); });
6554
+ const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-D1JA3cL4.js'); });
6410
6555
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
6411
6556
  break;
6412
6557
  }
@@ -6431,7 +6576,7 @@ async function getAuthProvider(config, fromStorage = false) {
6431
6576
  break;
6432
6577
  case "guest":
6433
6578
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
6434
- currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-5bX-xt6K.js'); })).GuestAuthProvider();
6579
+ currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-d6dk97x6.js'); })).GuestAuthProvider();
6435
6580
  break;
6436
6581
  }
6437
6582
  if (!currentAuthProvider) {
@@ -6493,7 +6638,7 @@ async function signInAnonymously() {
6493
6638
  // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
6494
6639
  // the main bundle for data-only apps. Specifier is a static string literal
6495
6640
  // so bundle-splitting can see it.
6496
- const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-5bX-xt6K.js'); })).GuestAuthProvider();
6641
+ const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-d6dk97x6.js'); })).GuestAuthProvider();
6497
6642
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
6498
6643
  // adoptSessionProvider awaits only getConfig() (already resolved here) and then
6499
6644
  // runs every write - provider/method/config/marker/user - in one synchronous
@@ -6664,7 +6809,7 @@ function ensureSharedWalletLoginReady() {
6664
6809
  if (!sharedWalletReady) {
6665
6810
  sharedWalletReady = (async () => {
6666
6811
  await core.getConfig();
6667
- await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
6812
+ await Promise.resolve().then(function () { return require('./injected-wallet-provider-BXFicWTx.js'); });
6668
6813
  })().catch((error) => {
6669
6814
  sharedWalletReady = null;
6670
6815
  throw error;
@@ -6746,10 +6891,12 @@ async function loginWithWallet(options) {
6746
6891
  // one that yields nothing and then a wallet prepares the mobile registry
6747
6892
  // after the tap for a wallet it never uses.
6748
6893
  const pinnedProvider = (_b = (_a = injectedConfig.getProvider) === null || _a === void 0 ? void 0 : _a.call(injectedConfig)) !== null && _b !== void 0 ? _b : null;
6894
+ if (injectedConfig.getProvider && !pinnedProvider)
6895
+ throw new Error(SELECTED_WALLET_UNAVAILABLE_ERR);
6749
6896
  const attemptConfig = Object.assign(Object.assign({}, injectedConfig), {
6750
- // Still a fallthrough when it resolved nothing, exactly as before - the
6751
- // difference is that the answer is now fixed for this attempt.
6752
- getProvider: () => pinnedProvider });
6897
+ // An explicit choice stays pinned. With no getter, retain default
6898
+ // discovery rather than manufacturing an unavailable explicit choice.
6899
+ getProvider: injectedConfig.getProvider ? () => pinnedProvider : undefined });
6753
6900
  // Idempotent: a caller that prepared the lane (the widget, or an app that
6754
6901
  // awaited ensureWalletLoginReady before enabling its button) has already
6755
6902
  // paid for this, so nothing activation-sensitive happens after the tap. A
@@ -6758,16 +6905,16 @@ async function loginWithWallet(options) {
6758
6905
  //
6759
6906
  // "Pinned" is about the EFFECTIVE resolution, not whether a getter was
6760
6907
  // passed: a configured walletLogin.getProvider pins just as much as a
6761
- // per-call one, and a getter that returns nothing falls through to discovery
6762
- // (and so to the mobile wallet). With a real wallet in hand only the shared
6763
- // half is needed - re-attempting a failed mobile registration would be
6908
+ // per-call one. An unavailable explicit choice was refused above. With a
6909
+ // real wallet in hand only the shared half is needed - re-attempting a
6910
+ // failed mobile registration would be
6764
6911
  // exactly the work-after-the-tap this exists to avoid, for a wallet this
6765
6912
  // login is not even using.
6766
6913
  if (pinnedProvider)
6767
6914
  await ensureSharedWalletLoginReady();
6768
6915
  else
6769
6916
  await ensureWalletLoginReady();
6770
- const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
6917
+ const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-BXFicWTx.js'); });
6771
6918
  // Keep the RAW wallet provider: the offchain wrapper forwards only a fixed
6772
6919
  // set of methods, so cleanup below must speak to the provider that actually
6773
6920
  // holds the config rather than to whatever is wrapping it.
@@ -7595,15 +7742,28 @@ function hasFeature(wallet, name) {
7595
7742
  function supportsSolana(wallet) {
7596
7743
  return wallet.chains.some((c) => c.startsWith("solana:"));
7597
7744
  }
7598
- /** A wallet is LISTED for Bounded login when it can connect + sign a message on a
7599
- * Solana chain. Login itself needs the `solana:signIn` feature (SEC-01); that is
7600
- * checked at login time in InjectedWalletProvider, where a wallet without it is
7601
- * refused with the reason spelled out rather than silently missing from the list.
7602
- * Transaction features are optional and checked lazily at call time. */
7603
- function isLoginCapable(wallet) {
7745
+ /** A Solana wallet the SDK can connect and use for message signing. */
7746
+ function isSolanaWallet(wallet) {
7747
+ var _a, _b;
7604
7748
  return (supportsSolana(wallet) &&
7605
- hasFeature(wallet, StandardConnect) &&
7606
- hasFeature(wallet, SolanaSignMessage));
7749
+ typeof ((_a = feature(wallet, StandardConnect)) === null || _a === void 0 ? void 0 : _a.connect) === "function" &&
7750
+ typeof ((_b = feature(wallet, SolanaSignMessage)) === null || _b === void 0 ? void 0 : _b.signMessage) === "function");
7751
+ }
7752
+ /** Login choices must support the same SIWS operation login() requires.
7753
+ * Transaction features remain optional and are checked at call time. */
7754
+ function isLoginCapable(wallet) {
7755
+ var _a, _b;
7756
+ return isSolanaWallet(wallet) && supportsWalletSignIn({
7757
+ connect: (_a = feature(wallet, StandardConnect)) === null || _a === void 0 ? void 0 : _a.connect,
7758
+ signIn: (_b = feature(wallet, SolanaSignIn)) === null || _b === void 0 ? void 0 : _b.signIn,
7759
+ });
7760
+ }
7761
+ /** Distinguish unsupported installed wallets from an empty registry in the UI. */
7762
+ function hasUnsupportedStandardWallets(configuredNetwork) {
7763
+ if (typeof window === "undefined")
7764
+ return false;
7765
+ const chain = configuredNetwork ? solanaChainOrNull(configuredNetwork) : null;
7766
+ return getWallets().get().some((wallet) => (isSolanaWallet(wallet) && (!chain || wallet.chains.includes(chain)) && !isLoginCapable(wallet)));
7607
7767
  }
7608
7768
  /** The Wallet-Standard chain id for a configured network, or null when it is
7609
7769
  * absent/unsupported. Ordering must never throw - failing closed on an
@@ -7632,6 +7792,7 @@ function feature(wallet, name) {
7632
7792
  * an unconfigured network fails closed at sign time rather than defaulting.
7633
7793
  */
7634
7794
  function standardWalletToInjectedProvider(wallet, configuredNetwork) {
7795
+ var _a;
7635
7796
  // The adapter holds NO account of its own: `wallet.accounts` is the Wallet
7636
7797
  // Standard's live authorized-account view, kept in sync by the wallet itself
7637
7798
  // (it emits standard:events 'change' when it moves). Reading it on every
@@ -7731,12 +7892,12 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
7731
7892
  const disconnect = feature(wallet, StandardDisconnect);
7732
7893
  if (disconnect)
7733
7894
  await disconnect.disconnect();
7734
- } }, (hasFeature(wallet, SolanaSignIn)
7895
+ } }, (typeof ((_a = feature(wallet, SolanaSignIn)) === null || _a === void 0 ? void 0 : _a.signIn) === "function"
7735
7896
  ? {
7736
7897
  async signIn(input) {
7737
7898
  var _a;
7738
7899
  const sign = feature(wallet, SolanaSignIn);
7739
- if (!sign)
7900
+ if (typeof (sign === null || sign === void 0 ? void 0 : sign.signIn) !== "function")
7740
7901
  throw new Error("Wallet does not support solana:signIn");
7741
7902
  const open = currentAccount();
7742
7903
  if (open && !accountSupports(open, SolanaSignIn))
@@ -8284,14 +8445,12 @@ function walletGlyph() {
8284
8445
  return svg;
8285
8446
  }
8286
8447
  function isInjectedProvider(v) {
8287
- return (typeof v === "object" &&
8288
- v !== null &&
8289
- typeof v.signMessage === "function");
8448
+ return supportsWalletSignIn(v);
8290
8449
  }
8291
8450
  // Enumerate native wallets via the Solana Wallet Standard registry (NOT a
8292
- // hardcoded name list) - every wallet that registered itself shows up with its
8293
- // real name + icon - and ALSO an older wallet that never registers and only
8294
- // exposes `window.solana`.
8451
+ // hardcoded name list) - wallets that support Bounded sign-in show up with
8452
+ // their real name + icon - and ALSO an eligible older wallet that never
8453
+ // registers and only exposes `window.solana`.
8295
8454
  //
8296
8455
  // The legacy `window.solana` probe fills in for a wallet too old to register
8297
8456
  // itself. The rule it has always encoded is "no BROWSER wallet registered", and
@@ -8326,7 +8485,11 @@ const BUSY_MSG = "A sign-in is already in progress - finish or cancel it first."
8326
8485
  // no wallet in this browser). A phone browser never sees installed wallet apps
8327
8486
  // as injected providers, so the honest advice there is a different browser,
8328
8487
  // not "install a wallet".
8329
- function noLaneCopy(mobile) {
8488
+ function noLaneCopy(mobile, unsupportedWallets) {
8489
+ if (unsupportedWallets) {
8490
+ return "The wallets detected in this browser cannot sign in to Bounded. " +
8491
+ "Use a wallet that supports Sign In With Solana, then reload this page.";
8492
+ }
8330
8493
  return mobile
8331
8494
  ? "No wallet is available in this browser. Open this page in your wallet app's " +
8332
8495
  "browser, or on a desktop browser with a wallet extension, then try again."
@@ -8524,6 +8687,9 @@ async function prepareAndOpen(opts, pending) {
8524
8687
  // button with no wallet behind it.
8525
8688
  if (wallets.length === 0)
8526
8689
  walletEnabled = false;
8690
+ const defaultWallet = defaultInjectedProvider();
8691
+ const unsupportedWallets = !lane.hardOff && lane.requested !== false && (hasUnsupportedStandardWallets(network) ||
8692
+ (defaultWallet !== null && !supportsWalletSignIn(defaultWallet)));
8527
8693
  const authMode = (_b = opts.authMode) !== null && _b !== void 0 ? _b : authApi.resolveAuthMode(initCfg);
8528
8694
  // Widget text: per-call options win, then init() loginWidget config, then the
8529
8695
  // defaults ("Sign in" / the Bounded subline; "" suppresses the subline).
@@ -8902,14 +9068,19 @@ async function prepareAndOpen(opts, pending) {
8902
9068
  // screen, and name the usual cause once in the console, where the
8903
9069
  // developer's own preview run will show it.
8904
9070
  if (!hasEmail && social.length === 0 && !walletEnabled) {
8905
- card.appendChild(el("p", "sub", noLaneCopy(detectMobile())));
9071
+ card.appendChild(el("p", "sub", noLaneCopy(detectMobile(), unsupportedWallets)));
8906
9072
  console.warn("[Bounded] openBoundedWidget has no sign-in lane to show: the app asked for " +
8907
- "no email or social method and no wallet is available in this browser. " +
8908
- (offerMobile
9073
+ "no email or social method and " +
9074
+ (unsupportedWallets
9075
+ ? "the detected wallets do not support Sign In With Solana. "
9076
+ : "no wallet is available in this browser. ") +
9077
+ (offerMobile && !unsupportedWallets
8909
9078
  ? "On Android the Solana Mobile wallet is offered only when the app installs " +
8910
9079
  "'@solana-mobile/wallet-standard-mobile' (see the warning above if registration failed); "
8911
9080
  : "") +
8912
- "Add a method, or make sure wallet login is enabled and the mobile adapter is installed.");
9081
+ (unsupportedWallets
9082
+ ? "Add another sign-in method, or use a wallet that supports Sign In With Solana."
9083
+ : "Add a method, or make sure wallet login is enabled and the mobile adapter is installed."));
8913
9084
  }
8914
9085
  card.appendChild(status);
8915
9086
  const foot = el("div", "foot");
@@ -10496,7 +10667,7 @@ async function onrampStatus(sinceMs) {
10496
10667
  function isSuccess(t) {
10497
10668
  return /SUCCESS|COMPLETED/i.test(t.status);
10498
10669
  }
10499
- function isPending(t) {
10670
+ function isPending$1(t) {
10500
10671
  return /PROGRESS|PENDING|CREATED/i.test(t.status);
10501
10672
  }
10502
10673
  async function verifyCompletion(openedAt, asset, timeoutMs) {
@@ -10510,7 +10681,7 @@ async function verifyCompletion(openedAt, asset, timeoutMs) {
10510
10681
  const done = txs.find((t) => isSuccess(t) && (t.asset === null || t.asset === asset));
10511
10682
  if (done)
10512
10683
  return done;
10513
- sawPending = txs.some(isPending);
10684
+ sawPending = txs.some(isPending$1);
10514
10685
  }
10515
10686
  catch ( /* transient - keep polling until the deadline */_a) { /* transient - keep polling until the deadline */ }
10516
10687
  // No completed fill and nothing in flight: one grace poll cycle still
@@ -10616,6 +10787,570 @@ async function onramp(options = {}) {
10616
10787
  return Object.assign(Object.assign({}, base), { status: 'closed' });
10617
10788
  }
10618
10789
 
10790
+ // venue-escrow.ts - fund and dispute a venue escrow from inside an OpenApps app (VENUE-GRANT-DESIGN.md).
10791
+ //
10792
+ // An OpenApps app's escrow lives in its venue (`agentescrows/<rootAppId>/e/<escrowId>`), and this
10793
+ // app's session cannot write another app's data. Bounded Auth therefore mints a 5 minute,
10794
+ // single-use GRANT for exactly one create (`POST {humanAuthApiUrl}/app-token/venue-grant`;
10795
+ // contract: packages/cdk/cloudflare/shared/venue-grant.ts, which the SDK cannot import because the
10796
+ // packages publish separately, so only what is needed is mirrored here), and the venue builds the
10797
+ // transaction for the wallet signed in here. The money's only authority is that wallet's
10798
+ // signature, checked onchain by the venue's own rule; the grant adds no power to the app.
10799
+ //
10800
+ // Funding moves money, so it keeps the recovery semantics oapps-fun's retired escrow page proved:
10801
+ // a pending record is saved BEFORE any network call and checked before ever funding again; the
10802
+ // escrow id is stable across retries; an uncertain broadcast is settled by its signature or the
10803
+ // public receipt and never re-sent; one tab funds at a time; and a row that does not match every
10804
+ // term is `taken`, never funded.
10805
+ /** Thrown by every venue escrow call. Branch on `code`; `error.name === 'VenueEscrowError'` also holds across bundled SDK copies. */
10806
+ class VenueEscrowError extends Error {
10807
+ constructor(code, message, details = {}) {
10808
+ super(message);
10809
+ this.name = 'VenueEscrowError';
10810
+ this.code = code;
10811
+ if (details.escrowId !== undefined)
10812
+ this.escrowId = details.escrowId;
10813
+ if (details.cause !== undefined)
10814
+ this.cause = details.cause;
10815
+ }
10816
+ }
10817
+ const ESCROW_SCHEMA = 'openapps.agent-escrow.v1';
10818
+ const STORAGE_PREFIX = 'bounded.venue-escrow-funding.v1';
10819
+ /** A saved funding that shows no row and no signature this long after its save can no longer land. */
10820
+ const ABANDONED_MS = 5 * 60000;
10821
+ const RECEIPT_POLL_MS = [0, 250, 500, 1000, 1500, 2500, 4000];
10822
+ const ADDRESS = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
10823
+ const APP_ID = /^[0-9a-f]{24}$/;
10824
+ const RECORD_ID = /^[0-9a-f]{32}$/;
10825
+ /**
10826
+ * Bounded Auth's own refusals of a grant mint, passed through as codes, with what each means to a
10827
+ * person: the error's message, and so what the reserved signer window shows before it closes.
10828
+ */
10829
+ const GRANT_REFUSALS = {
10830
+ invalid_request: 'The request was not accepted. Update the app and try again.',
10831
+ invalid_token: 'Your session expired. Sign in again.',
10832
+ origin_not_allowed: "This site isn't allowed to fund escrows for this app.",
10833
+ not_an_openapps_app: "This app can't fund escrows.",
10834
+ wallet_required: 'Sign in with a wallet to fund escrows.',
10835
+ agent_wallet_refused: "An agent's wallet can't fund escrows here.",
10836
+ rate_limited: 'Too many attempts. Try again in a minute.',
10837
+ venue_grant_unavailable: 'Escrows are unavailable right now. Try again shortly.',
10838
+ };
10839
+ const nowSeconds = () => Math.floor(Date.now() / 1000);
10840
+ /** A v0 dispute transaction stops fitting past about 513 reason bytes; this keeps a margin. */
10841
+ const MAX_DISPUTE_REASON_BYTES = 400;
10842
+ const isCount = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
10843
+ const newRecordId = () => Array.from(getPlatform().getRandomBytes(16), (byte) => byte.toString(16).padStart(2, '0')).join('');
10844
+ const pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10845
+ /** Mirrors `venueGrantPath` in shared/venue-grant.ts: the one path a grant of this kind may create. */
10846
+ function recordPath(kind, rootAppId, id) {
10847
+ return kind === 'escrow' ? `agentescrows/${rootAppId}/e/${id}` : `agentescrowdisputes/${rootAppId}/d/${id}`;
10848
+ }
10849
+ /** Who is signed in, read synchronously: the click handler must not await before it reserves the signer window. */
10850
+ function sessionIdentity() {
10851
+ const appId = core.getConfiguredAppId();
10852
+ let idToken = null;
10853
+ try {
10854
+ idToken = core.getActiveSessionManager().getIdToken();
10855
+ }
10856
+ catch ( /* no session store */_a) { /* no session store */ }
10857
+ if (!appId || !idToken)
10858
+ throw new VenueEscrowError('sign_in_required', 'Sign in before using venue escrows.');
10859
+ const wallet = core.deriveUserIdentityFromIdToken(idToken).address;
10860
+ if (!wallet)
10861
+ throw new VenueEscrowError('wallet_required', 'This session has no wallet to sign with.');
10862
+ return { appId, wallet };
10863
+ }
10864
+ async function mintGrant(kind, id, wallet) {
10865
+ var _a;
10866
+ let idToken = null;
10867
+ try {
10868
+ idToken = await core.getFreshAuthToken(false);
10869
+ }
10870
+ catch ( /* an expired session reads as signed out */_b) { /* an expired session reads as signed out */ }
10871
+ if (!idToken)
10872
+ throw new VenueEscrowError('sign_in_required', 'Your session expired. Sign in again.');
10873
+ if (core.deriveUserIdentityFromIdToken(idToken).address !== wallet) {
10874
+ throw new VenueEscrowError('wallet_changed', 'The signed-in wallet changed. Start again.');
10875
+ }
10876
+ const base = ((await core.getConfig()).humanAuthApiUrl || 'https://auth.bounded.sh').replace(/\/$/, '');
10877
+ let response;
10878
+ try {
10879
+ response = await fetch(`${base}/app-token/venue-grant`, {
10880
+ method: 'POST',
10881
+ headers: { 'content-type': 'application/json' },
10882
+ body: JSON.stringify({ idToken, kind, id, walletProtocol: 2 }),
10883
+ });
10884
+ }
10885
+ catch (cause) {
10886
+ throw new VenueEscrowError('venue_grant_unavailable', 'Could not reach Bounded Auth to authorize this write.', { cause });
10887
+ }
10888
+ const body = (await response.json().catch(() => null));
10889
+ if (!response.ok) {
10890
+ const error = typeof (body === null || body === void 0 ? void 0 : body.error) === 'string' ? body.error : '';
10891
+ const code = Object.keys(GRANT_REFUSALS).includes(error) ? error : response.status >= 500 ? 'venue_grant_unavailable' : 'venue_grant_refused';
10892
+ throw new VenueEscrowError(code, (_a = GRANT_REFUSALS[code]) !== null && _a !== void 0 ? _a : `Bounded Auth refused the venue grant (${error || response.status}).`);
10893
+ }
10894
+ const fields = body !== null && body !== void 0 ? body : {};
10895
+ const { grant, venueAppId, rootAppId, walletAddress, path } = fields;
10896
+ if (typeof grant !== 'string' || !grant || typeof venueAppId !== 'string' || !APP_ID.test(venueAppId)
10897
+ || typeof rootAppId !== 'string' || !APP_ID.test(rootAppId) || walletAddress !== wallet || path !== recordPath(kind, rootAppId, id)) {
10898
+ throw new VenueEscrowError('venue_grant_unavailable', 'Bounded Auth answered with a grant that does not match this write.');
10899
+ }
10900
+ return { grant, venueAppId, rootAppId, path };
10901
+ }
10902
+ /* ------------------------------- reading -------------------------------- */
10903
+ /**
10904
+ * Read one venue escrow from the public record: its terms and its state (`pending` until the
10905
+ * venue's hook completes, `failed` when it did not). Resolves null when no such escrow exists.
10906
+ * No sign-in is needed.
10907
+ */
10908
+ async function getVenueEscrow(input) {
10909
+ var _a;
10910
+ const { rootAppId, escrowId } = input !== null && input !== void 0 ? input : {};
10911
+ if (!APP_ID.test(String(rootAppId)) || !RECORD_ID.test(String(escrowId))) {
10912
+ throw new VenueEscrowError('invalid_input', 'getVenueEscrow needs a rootAppId (24 hex characters) and an escrowId (32 hex characters).');
10913
+ }
10914
+ const base = (_a = (await core.getConfig()).devApiUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/$/, '');
10915
+ if (!base)
10916
+ throw new VenueEscrowError('read_unavailable', 'The Bounded developer API is not configured. Pass a Bounded network to init().');
10917
+ let response;
10918
+ try {
10919
+ // The 200 is cacheable for a minute, and a funding is polled through `pending`.
10920
+ response = await fetch(`${base}/public/oapp/${rootAppId}/escrows/${escrowId}`, { cache: 'no-store' });
10921
+ }
10922
+ catch (cause) {
10923
+ throw new VenueEscrowError('read_unavailable', 'Could not reach the Bounded developer API.', { cause });
10924
+ }
10925
+ if (response.status === 404)
10926
+ return null;
10927
+ const body = (await response.json().catch(() => null));
10928
+ if (!response.ok || (body === null || body === void 0 ? void 0 : body.ok) !== true || !body.escrow || typeof body.escrow !== 'object') {
10929
+ throw new VenueEscrowError('read_unavailable', `The escrow could not be read (${response.status}).`);
10930
+ }
10931
+ return body.escrow;
10932
+ }
10933
+ /**
10934
+ * The overrides that point a receipt's reconciliation at the venue it was issued for and the RPC of
10935
+ * the chain it ran on (the same one the write was broadcast through), with no credential.
10936
+ */
10937
+ async function venueReadOverrides(venueAppId, chain) {
10938
+ var _a;
10939
+ const config = await core.getConfig();
10940
+ const rpcUrl = (_a = core.resolveVenueRpcUrl(config, chain, defaultSolanaRpcUrl)) !== null && _a !== void 0 ? _a : config.rpcUrl;
10941
+ return { _config: Object.assign(Object.assign({}, config), { appId: venueAppId, rpcUrl }), _readOnly: true };
10942
+ }
10943
+ const TERM_KEYS = ['payee', 'amountUsdc', 'challengeSeconds', 'expiresAt', 'ref'];
10944
+ /** Every term the funder signed, which a row must carry in full to be this funding. */
10945
+ const ROW_KEYS = ['schemaVersion', 'funder', 'payee', 'amountUsdc', 'challengeSeconds', 'expiresAt', 'ref', 'at'];
10946
+ /** The first thing wrong with these terms, or null. Shapes only: the venue's rule owns every bound. */
10947
+ function termsProblem(terms, wallet) {
10948
+ if (!terms || typeof terms.payee !== 'string' || !ADDRESS.test(terms.payee))
10949
+ return 'payee must be a Solana address';
10950
+ if (terms.payee === wallet)
10951
+ return 'payee must not be the wallet that is funding';
10952
+ for (const key of ['amountUsdc', 'challengeSeconds', 'expiresAt']) {
10953
+ if (!isCount(terms[key]))
10954
+ return `${key} must be a non-negative integer`;
10955
+ }
10956
+ if (typeof terms.ref !== 'string' || terms.ref.length < 1 || terms.ref.length > 128)
10957
+ return 'ref must be 1 to 128 characters';
10958
+ return null;
10959
+ }
10960
+ function isSavedSubmission(value) {
10961
+ var _a, _b;
10962
+ const saved = value;
10963
+ return !!saved && saved.status === 'submitted' && typeof saved.appId === 'string' && typeof saved.chain === 'string'
10964
+ && typeof saved.transactionId === 'string' && saved.transactionId.length > 0
10965
+ && typeof saved.signedTransaction === 'string' && Array.isArray(saved.requestedDocuments)
10966
+ && typeof ((_a = saved.fence) === null || _a === void 0 ? void 0 : _a.blockhash) === 'string' && Number.isSafeInteger((_b = saved.fence) === null || _b === void 0 ? void 0 : _b.lastValidBlockHeight);
10967
+ }
10968
+ function isPending(value, wallet) {
10969
+ const doc = value === null || value === void 0 ? void 0 : value.document;
10970
+ const sent = (value === null || value === void 0 ? void 0 : value.path) !== undefined;
10971
+ return RECORD_ID.test(String(value === null || value === void 0 ? void 0 : value.escrowId)) && Number.isSafeInteger(value.savedAtMs) && value.savedAtMs > 0
10972
+ && !!doc && doc.schemaVersion === ESCROW_SCHEMA && doc.funder === wallet && termsProblem(doc, wallet) === null && isCount(doc.at)
10973
+ && [doc.approvedAt, doc.approvedKind, doc.approvalId, doc.disputedAt, doc.disputedBy, doc.settledAt, doc.settledKind, doc.settledBy].every((field) => field === null)
10974
+ && (!sent || (APP_ID.test(String(value.rootAppId)) && APP_ID.test(String(value.venueAppId)) && value.path === recordPath('escrow', value.rootAppId, value.escrowId)))
10975
+ && (value.submission === undefined || isSavedSubmission(value.submission));
10976
+ }
10977
+ function store() {
10978
+ const storage = getPlatform().storage;
10979
+ // A volatile fallback would forget a funding that may have landed, and the next click would send a second one.
10980
+ if (isVolatileStorage(storage))
10981
+ throw new VenueEscrowError('storage_unavailable', 'Venue escrow funding needs durable browser storage.');
10982
+ return storage;
10983
+ }
10984
+ function loadPending(key, wallet) {
10985
+ const storage = store();
10986
+ try {
10987
+ const raw = storage.getItem(key);
10988
+ if (!raw)
10989
+ return null;
10990
+ const value = JSON.parse(raw);
10991
+ if (!isPending(value, wallet))
10992
+ throw new Error('malformed');
10993
+ return value;
10994
+ }
10995
+ catch (_a) {
10996
+ throw new VenueEscrowError('storage_unavailable', 'The saved escrow funding could not be read, so another one will not be started.');
10997
+ }
10998
+ }
10999
+ function savePending(key, pending) {
11000
+ const storage = store();
11001
+ try {
11002
+ storage.setItem(key, JSON.stringify(pending));
11003
+ }
11004
+ catch (_a) {
11005
+ throw new VenueEscrowError('storage_unavailable', 'The escrow funding could not be saved, so it was not sent.');
11006
+ }
11007
+ }
11008
+ function clearPending(key, escrowId) {
11009
+ try {
11010
+ const raw = store().getItem(key);
11011
+ if (raw && JSON.parse(raw).escrowId === escrowId)
11012
+ store().removeItem(key);
11013
+ }
11014
+ catch ( /* unreadable: the next call refuses to fund over it */_a) { /* unreadable: the next call refuses to fund over it */ }
11015
+ }
11016
+ function rowVerdict(pending, row) {
11017
+ var _a, _b;
11018
+ if (!ROW_KEYS.every((key) => row[key] === pending.document[key]))
11019
+ return { state: 'taken' };
11020
+ if (row.state === 'failed')
11021
+ return { state: 'failed' };
11022
+ if (row.state === 'pending')
11023
+ return { state: 'pending' };
11024
+ return { state: 'completed', transactionId: (_b = (_a = pending.submission) === null || _a === void 0 ? void 0 : _a.transactionId) !== null && _b !== void 0 ? _b : null };
11025
+ }
11026
+ /** Settle a saved funding without sending anything: the public row first, then its signature, then its age. */
11027
+ async function checkPending(pending) {
11028
+ if (!pending.path)
11029
+ return { state: 'not_applied', reason: 'it was interrupted before the venue was asked.' };
11030
+ let row;
11031
+ try {
11032
+ row = await getVenueEscrow({ rootAppId: pending.rootAppId, escrowId: pending.escrowId });
11033
+ }
11034
+ catch (_a) {
11035
+ return { state: 'pending' };
11036
+ }
11037
+ if (row)
11038
+ return rowVerdict(pending, row);
11039
+ if (pending.submission) {
11040
+ try {
11041
+ const settled = await core.reconcileSetResult(pending.submission, { _overrides: await venueReadOverrides(pending.venueAppId, pending.submission.chain) });
11042
+ if (settled.status === 'confirmed')
11043
+ return { state: 'completed', transactionId: settled.transactionId };
11044
+ if (settled.status === 'expired_not_landed')
11045
+ return { state: 'not_applied', reason: 'it expired before it reached the chain.' };
11046
+ }
11047
+ catch (error) {
11048
+ if (core.writeNotAppliedPhase(error) !== null)
11049
+ return { state: 'not_applied', reason: 'the transaction failed onchain.' };
11050
+ }
11051
+ return { state: 'pending' };
11052
+ }
11053
+ return Date.now() - pending.savedAtMs >= ABANDONED_MS
11054
+ ? { state: 'not_applied', reason: 'no transaction was ever recorded for it, and it can no longer land.' }
11055
+ : { state: 'pending' };
11056
+ }
11057
+ /** Poll the public row until it settles: a direct poofnet commit is not funded until the venue's hook stamps it. */
11058
+ async function awaitRow(pending) {
11059
+ for (const delay of RECEIPT_POLL_MS) {
11060
+ if (delay)
11061
+ await pause(delay);
11062
+ let row = null;
11063
+ try {
11064
+ row = await getVenueEscrow({ rootAppId: pending.rootAppId, escrowId: pending.escrowId });
11065
+ }
11066
+ catch ( /* keep polling */_a) { /* keep polling */ }
11067
+ const verdict = row ? rowVerdict(pending, row) : null;
11068
+ if (verdict && verdict.state !== 'pending')
11069
+ return verdict;
11070
+ }
11071
+ return { state: 'pending' };
11072
+ }
11073
+ /** The one place a funding ends: return its result, or release the saved record and throw why not. */
11074
+ function conclude(key, pending, verdict, terms) {
11075
+ const { escrowId } = pending;
11076
+ if (verdict.state === 'pending') {
11077
+ throw new VenueEscrowError('pending', 'The funding is not confirmed yet. Call fundVenueEscrow again with the same terms to check it; do not start another.', { escrowId });
11078
+ }
11079
+ clearPending(key, escrowId);
11080
+ switch (verdict.state) {
11081
+ case 'completed':
11082
+ if (terms && !TERM_KEYS.every((term) => pending.document[term] === terms[term])) {
11083
+ throw new VenueEscrowError('funded_other_terms', `An earlier, interrupted funding with different terms landed as escrow ${escrowId}. Check it with getVenueEscrow before funding again.`, { escrowId });
11084
+ }
11085
+ return { escrowId, rootAppId: pending.rootAppId, venueAppId: pending.venueAppId, transactionId: verdict.transactionId };
11086
+ case 'taken':
11087
+ throw new VenueEscrowError('taken', 'A different record already holds this escrow id, so this funding did not land.', { escrowId });
11088
+ case 'failed':
11089
+ throw new VenueEscrowError('failed', 'The venue accepted the funding but its hook failed, so nothing moved. Try again.', { escrowId });
11090
+ default:
11091
+ throw new VenueEscrowError('not_applied', `The funding did not go through: ${verdict.reason} nothing moved. Try again.`, { escrowId });
11092
+ }
11093
+ }
11094
+ /**
11095
+ * Read a thrown write: what the SDK, the wallet or the venue said, as a code. The venue's own code
11096
+ * is read before its status, because a 403 is not always its rule: a grant outside its scope
11097
+ * (`venue_grant_scope`), a forbidden precondition or a signer that does not match the signing
11098
+ * request are not, and only a decline (or the program's own rule rejection) is `rule_refused`.
11099
+ */
11100
+ function mapWriteError(error) {
11101
+ var _a;
11102
+ if (error instanceof VenueEscrowError)
11103
+ return error;
11104
+ const e = (error !== null && error !== void 0 ? error : {});
11105
+ const text = typeof e.message === 'string' ? e.message : String(error);
11106
+ const code = e.code === 'chain_mismatch' || e.code === 'chain_not_configured' || e.code === 'sponsorship_refused' || e.code === 'sponsorship_unavailable' ? e.code
11107
+ : e.name === 'InsufficientBalanceError' ? 'insufficient_balance'
11108
+ : e.code === 'venue_grant_scope' || e.statusCode === 401 ? 'grant_rejected'
11109
+ : e.isBoundedDecline === true || e.boundedRuleRejection === true ? 'rule_refused'
11110
+ : e.statusCode === 429 ? 'rate_limited'
11111
+ : /^top_level_required/.test(text) ? 'top_level_required'
11112
+ : /popup blocked/i.test(text) ? 'popup_blocked'
11113
+ // The wallet's or the window's own words only: a venue answer that happens to say "denied" is not the user declining.
11114
+ : e.statusCode === undefined && /user rejected|rejected the request|declined|denied|cancel|window was closed/i.test(text) ? 'declined'
11115
+ : 'write_failed';
11116
+ const message = code === 'rule_refused' && typeof ((_a = e.decline) === null || _a === void 0 ? void 0 : _a.message) === 'string' ? e.decline.message
11117
+ : e.boundedRuleRejection === true ? 'The venue\'s onchain rules refused this write, usually because the approval took longer than the two minutes a write stays valid. Start again.'
11118
+ : text;
11119
+ return new VenueEscrowError(code, message, { cause: error });
11120
+ }
11121
+ /** What a write that returned, rather than threw, means for this funding. */
11122
+ async function settleResult(key, pending, result, terms) {
11123
+ var _a;
11124
+ let current = result;
11125
+ if (current.status === 'submitted') {
11126
+ try {
11127
+ current = await core.waitForSetResult(current, { _overrides: await venueReadOverrides(pending.venueAppId, current.chain), timeoutMs: 60000 });
11128
+ }
11129
+ catch (error) {
11130
+ if (core.writeNotAppliedPhase(error) !== null) {
11131
+ clearPending(key, pending.escrowId);
11132
+ throw mapWriteError(error);
11133
+ }
11134
+ }
11135
+ }
11136
+ switch (current.status) {
11137
+ case 'confirmed':
11138
+ return conclude(key, pending, { state: 'completed', transactionId: current.transactionId }, terms);
11139
+ case 'committed': {
11140
+ const verdict = await awaitRow(pending);
11141
+ return conclude(key, pending, verdict.state === 'completed' ? { state: 'completed', transactionId: (_a = current.transactionId) !== null && _a !== void 0 ? _a : verdict.transactionId } : verdict, terms);
11142
+ }
11143
+ case 'expired_not_landed':
11144
+ return conclude(key, pending, { state: 'not_applied', reason: 'it expired before it reached the chain.' }, terms);
11145
+ case 'signed':
11146
+ return conclude(key, pending, { state: 'not_applied', reason: 'it was signed but never sent.' }, terms);
11147
+ default:
11148
+ return conclude(key, pending, { state: 'pending' }, terms);
11149
+ }
11150
+ }
11151
+ async function fundOrCheck(key, wallet, terms) {
11152
+ const saved = loadPending(key, wallet);
11153
+ if (saved)
11154
+ return conclude(key, saved, await checkPending(saved), terms);
11155
+ let pending = {
11156
+ escrowId: newRecordId(),
11157
+ savedAtMs: Date.now(),
11158
+ document: {
11159
+ payee: terms.payee, amountUsdc: terms.amountUsdc, challengeSeconds: terms.challengeSeconds, expiresAt: terms.expiresAt, ref: terms.ref,
11160
+ schemaVersion: ESCROW_SCHEMA, funder: wallet, at: nowSeconds(),
11161
+ approvedAt: null, approvedKind: null, approvalId: null, disputedAt: null, disputedBy: null,
11162
+ settledAt: null, settledKind: null, settledBy: null,
11163
+ },
11164
+ };
11165
+ const { escrowId } = pending;
11166
+ savePending(key, pending); // before any network call: the id must survive a lost answer
11167
+ let minted;
11168
+ try {
11169
+ minted = await mintGrant('escrow', escrowId, wallet);
11170
+ // The venue's rule holds `at` within two minutes of the chain clock, and the venue bakes it into the
11171
+ // transaction it builds from this write, so it is taken as late as it can be: after the mint, in the save
11172
+ // that adds the venue path, right before the write. The id and document were already saved before any
11173
+ // network call, and nothing has reached the venue yet, so recovery is unchanged.
11174
+ pending = Object.assign(Object.assign({}, pending), { document: Object.assign(Object.assign({}, pending.document), { at: nowSeconds() }), rootAppId: minted.rootAppId, venueAppId: minted.venueAppId, path: minted.path });
11175
+ savePending(key, pending);
11176
+ }
11177
+ catch (error) {
11178
+ clearPending(key, escrowId); // the venue was never asked, so there is nothing to settle
11179
+ throw error;
11180
+ }
11181
+ let result;
11182
+ try {
11183
+ result = await core.setWithVenueGrant(minted.path, pending.document, {
11184
+ venueAppId: minted.venueAppId,
11185
+ grant: minted.grant,
11186
+ commitGrant: async () => (await mintGrant('escrow', escrowId, wallet)).grant,
11187
+ resolveRpcUrl: defaultSolanaRpcUrl,
11188
+ onBroadcast: (submission) => {
11189
+ const next = Object.assign(Object.assign({}, pending), { submission });
11190
+ savePending(key, next);
11191
+ pending = next;
11192
+ },
11193
+ });
11194
+ }
11195
+ catch (error) {
11196
+ if (core.writeNotAppliedPhase(error) !== null) {
11197
+ clearPending(key, escrowId);
11198
+ throw mapWriteError(error);
11199
+ }
11200
+ // Anything else may follow a commit or broadcast whose answer was lost: settle it by the public
11201
+ // row, then by the saved signature. Never send again.
11202
+ const verdict = await awaitRow(pending);
11203
+ return conclude(key, pending, verdict.state === 'pending' && pending.submission ? await checkPending(pending) : verdict, terms);
11204
+ }
11205
+ return settleResult(key, pending, result, terms);
11206
+ }
11207
+ /** Poll the escrow until it shows disputed: a direct poofnet commit is not a dispute until the venue's hook stamps it. */
11208
+ async function awaitDisputed(rootAppId, escrowId) {
11209
+ for (const delay of RECEIPT_POLL_MS) {
11210
+ if (delay)
11211
+ await pause(delay);
11212
+ const row = await getVenueEscrow({ rootAppId, escrowId }).catch(() => null);
11213
+ if (row && row.disputedAt !== null)
11214
+ return true;
11215
+ }
11216
+ return false;
11217
+ }
11218
+ async function dispute(wallet, escrowId, reason) {
11219
+ const disputeId = newRecordId();
11220
+ const minted = await mintGrant('dispute', disputeId, wallet);
11221
+ let result = null;
11222
+ try {
11223
+ result = await core.setWithVenueGrant(minted.path, { escrowId, reason, at: nowSeconds() }, {
11224
+ venueAppId: minted.venueAppId,
11225
+ grant: minted.grant,
11226
+ commitGrant: async () => (await mintGrant('dispute', disputeId, wallet)).grant,
11227
+ resolveRpcUrl: defaultSolanaRpcUrl,
11228
+ });
11229
+ if (result.status === 'submitted')
11230
+ result = await core.waitForSetResult(result, { _overrides: await venueReadOverrides(minted.venueAppId, result.chain), timeoutMs: 60000 });
11231
+ }
11232
+ catch (error) {
11233
+ if (core.writeNotAppliedPhase(error) !== null)
11234
+ throw mapWriteError(error);
11235
+ // Anything else may follow a commit or broadcast whose answer was lost: the escrow says.
11236
+ }
11237
+ const done = { disputeId, rootAppId: minted.rootAppId, venueAppId: minted.venueAppId };
11238
+ if ((result === null || result === void 0 ? void 0 : result.status) === 'confirmed')
11239
+ return Object.assign(Object.assign({}, done), { transactionId: result.transactionId });
11240
+ if ((result === null || result === void 0 ? void 0 : result.status) === 'expired_not_landed' || (result === null || result === void 0 ? void 0 : result.status) === 'signed') {
11241
+ throw new VenueEscrowError('not_applied', 'The dispute never reached the chain, so nothing was sent. Try again.', { escrowId });
11242
+ }
11243
+ if (await awaitDisputed(minted.rootAppId, escrowId)) {
11244
+ return Object.assign(Object.assign({}, done), { transactionId: (result === null || result === void 0 ? void 0 : result.status) === 'committed' ? result.transactionId : null });
11245
+ }
11246
+ throw new VenueEscrowError('pending', 'The dispute was sent but is not confirmed yet. Read the escrow with getVenueEscrow to see whether it shows as disputed.', { escrowId });
11247
+ }
11248
+ /* ----------------------------- one call at a time ------------------------------ */
11249
+ const flights = new Map();
11250
+ /**
11251
+ * Run `run` unless an identical call is already in flight (a double click shares its result) or a
11252
+ * different one is (refused, never silently answered with the other's result). A Turnkey session's
11253
+ * signer window is reserved here, synchronously, because this runs inside the click.
11254
+ */
11255
+ function startFlow(key, fingerprint, needsSigner, run) {
11256
+ let reservation = null;
11257
+ try {
11258
+ const current = flights.get(key);
11259
+ if (current) {
11260
+ if (current.fingerprint === fingerprint)
11261
+ return current.promise;
11262
+ throw new VenueEscrowError('in_progress', 'A different venue escrow request is already in progress for this wallet.');
11263
+ }
11264
+ if (hasTurnkeyWallet() && needsSigner()) {
11265
+ reservation = reserveSignerPopup();
11266
+ if (!reservation)
11267
+ throw new VenueEscrowError('popup_blocked', 'Call this from a click handler so the wallet approval window can open, and allow popups for this site.');
11268
+ }
11269
+ // A flow that fails before the signer loads (a grant the venue refuses, a rule) leaves the reserved
11270
+ // window to explain itself with the error's words for a moment; one that signed has closed it already.
11271
+ const settled = (error) => {
11272
+ var _a;
11273
+ if (((_a = flights.get(key)) === null || _a === void 0 ? void 0 : _a.promise) === promise)
11274
+ flights.delete(key);
11275
+ reservation === null || reservation === void 0 ? void 0 : reservation.release(error instanceof Error ? error.message : undefined);
11276
+ };
11277
+ const promise = run().then((value) => { settled(); return value; }, (error) => { settled(error); throw error; });
11278
+ flights.set(key, { fingerprint, promise });
11279
+ return promise;
11280
+ }
11281
+ catch (error) {
11282
+ reservation === null || reservation === void 0 ? void 0 : reservation.release(error instanceof Error ? error.message : undefined);
11283
+ return Promise.reject(error);
11284
+ }
11285
+ }
11286
+ /** One tab funds at a time: the saved record is shared by every tab of this browser. */
11287
+ function withLock(key, run) {
11288
+ var _a;
11289
+ const locks = (_a = globalThis.navigator) === null || _a === void 0 ? void 0 : _a.locks;
11290
+ if (!(locks === null || locks === void 0 ? void 0 : locks.request))
11291
+ return Promise.reject(new VenueEscrowError('lock_unavailable', 'Venue escrow funding needs the Web Locks API, so that one tab funds at a time.'));
11292
+ return locks.request(key, { ifAvailable: true }, async (lock) => {
11293
+ if (!lock)
11294
+ throw new VenueEscrowError('in_progress', 'This escrow is already being funded in another tab.');
11295
+ return run();
11296
+ });
11297
+ }
11298
+ /* --------------------------------- public API ---------------------------------- */
11299
+ /**
11300
+ * Lock USDC in the venue escrow for `terms.payee`, signed by the wallet signed in here.
11301
+ * MUST be called from a user click: an email (Turnkey) wallet's approval opens in its own Bounded
11302
+ * window, which a browser only allows inside the click (it is opened here, before anything is
11303
+ * awaited), and the approval shows the decoded terms. A Phantom or Wallet Standard wallet keeps
11304
+ * its own prompt. On a real-chain venue the transaction is broadcast on the VENUE's chain: through
11305
+ * the app's own `rpcUrl` when the app configured that same `chain` too (an `rpcUrl` alone does not
11306
+ * say which chain it speaks), otherwise through the platform's default RPC for the venue's chain, so
11307
+ * an app that never configured a chain just works. An app that configured a different `chain` is
11308
+ * refused (`chain_mismatch`) before anything is signed.
11309
+ *
11310
+ * Funding is made safe to retry: a funding that was interrupted (page closed, answer lost) is
11311
+ * saved before anything is sent, and the next call checks it instead of funding again, so pass
11312
+ * the same terms and it resolves to the same `escrowId`. Store `escrowId` on your own record.
11313
+ * See {@link VenueEscrowErrorCode} for the failures, and `pending` in particular.
11314
+ */
11315
+ function fundVenueEscrow(terms) {
11316
+ try {
11317
+ const { appId, wallet } = sessionIdentity();
11318
+ const problem = termsProblem(terms, wallet);
11319
+ if (problem)
11320
+ throw new VenueEscrowError('invalid_input', `fundVenueEscrow: ${problem}.`);
11321
+ const checked = {
11322
+ payee: terms.payee, amountUsdc: terms.amountUsdc, challengeSeconds: terms.challengeSeconds, expiresAt: terms.expiresAt, ref: terms.ref,
11323
+ };
11324
+ const key = `${STORAGE_PREFIX}:${appId}:${wallet}`;
11325
+ return startFlow(key, JSON.stringify(checked), () => !loadPending(key, wallet), () => withLock(key, () => fundOrCheck(key, wallet, checked)));
11326
+ }
11327
+ catch (error) {
11328
+ return Promise.reject(error);
11329
+ }
11330
+ }
11331
+ /**
11332
+ * Dispute a funded venue escrow as its funder (or payee), signed by the wallet signed in here.
11333
+ * MUST be called from a user click, for the same reason as {@link fundVenueEscrow}. `reason` is
11334
+ * 1 to 400 bytes of UTF-8: the venue allows 1000 characters, but a longer reason does not fit one
11335
+ * legacy-format transaction. Nothing is saved: a dispute that already landed makes the venue refuse
11336
+ * a second one (`rule_refused`).
11337
+ */
11338
+ function disputeVenueEscrow(input) {
11339
+ try {
11340
+ const { appId, wallet } = sessionIdentity();
11341
+ const { escrowId, reason } = input !== null && input !== void 0 ? input : {};
11342
+ if (!RECORD_ID.test(String(escrowId)))
11343
+ throw new VenueEscrowError('invalid_input', 'disputeVenueEscrow: escrowId must be 32 hex characters.');
11344
+ if (typeof reason !== 'string' || reason.length < 1 || new TextEncoder().encode(reason).length > MAX_DISPUTE_REASON_BYTES) {
11345
+ throw new VenueEscrowError('invalid_input', `disputeVenueEscrow: reason must be 1 to ${MAX_DISPUTE_REASON_BYTES} bytes.`);
11346
+ }
11347
+ return startFlow(`dispute:${appId}:${wallet}:${escrowId}`, reason, () => true, () => dispute(wallet, escrowId, reason));
11348
+ }
11349
+ catch (error) {
11350
+ return Promise.reject(error);
11351
+ }
11352
+ }
11353
+
10619
11354
  /**
10620
11355
  * DS3-0414: does the transaction already carry a REAL signer signature? A Solana
10621
11356
  * signature is computed over the compiled message, which INCLUDES recentBlockhash, so
@@ -11017,25 +11752,6 @@ class PrivyExpoProvider {
11017
11752
  }
11018
11753
  }
11019
11754
 
11020
- /**
11021
- * Default provider discovery: Phantom-first, then any Wallet-Standard
11022
- * `window.solana`. Kept tiny + synchronous (no heavy imports) so it works inside
11023
- * a user gesture and can be eagerly exported from the SDK entry.
11024
- */
11025
- function defaultInjectedProvider() {
11026
- var _a;
11027
- if (typeof window === 'undefined')
11028
- return null;
11029
- const w = window;
11030
- const phantom = (_a = w === null || w === void 0 ? void 0 : w.phantom) === null || _a === void 0 ? void 0 : _a.solana;
11031
- if (phantom && typeof phantom.signMessage === 'function')
11032
- return phantom;
11033
- const generic = w === null || w === void 0 ? void 0 : w.solana;
11034
- if (generic && typeof generic.signMessage === 'function')
11035
- return generic;
11036
- return null;
11037
- }
11038
-
11039
11755
  // injected-evm-wallet-types.ts — tiny, dependency-free surface for the EVM
11040
11756
  // WALLET LOGIN path (BYO wallet via SIWE). The EVM twin of
11041
11757
  // injected-wallet-types.ts: kept separate from injected-evm-wallet-provider.ts
@@ -11435,7 +12151,9 @@ exports.OffchainAuthProvider = OffchainAuthProvider;
11435
12151
  exports.PARK_REASONS = PARK_REASONS;
11436
12152
  exports.PrivyExpoProvider = PrivyExpoProvider;
11437
12153
  exports.RUN_STATES = RUN_STATES;
12154
+ exports.SELECTED_WALLET_UNAVAILABLE_ERR = SELECTED_WALLET_UNAVAILABLE_ERR;
11438
12155
  exports.TERMINAL_STATES = TERMINAL_STATES;
12156
+ exports.VenueEscrowError = VenueEscrowError;
11439
12157
  exports.WalletConfigError = WalletConfigError;
11440
12158
  exports.apps = apps;
11441
12159
  exports.bs58 = bs58;
@@ -11447,10 +12165,12 @@ exports.connectBroadcast = connectBroadcast;
11447
12165
  exports.connectServiceSession = connectServiceSession;
11448
12166
  exports.defaultInjectedEvmProvider = defaultInjectedEvmProvider;
11449
12167
  exports.defaultInjectedProvider = defaultInjectedProvider;
12168
+ exports.disputeVenueEscrow = disputeVenueEscrow;
11450
12169
  exports.ensureSharedWalletLoginReady = ensureSharedWalletLoginReady;
11451
12170
  exports.ensureSignedIn = ensureSignedIn;
11452
12171
  exports.ensureWalletLoginReady = ensureWalletLoginReady;
11453
12172
  exports.firstStandardWalletProvider = firstStandardWalletProvider;
12173
+ exports.fundVenueEscrow = fundVenueEscrow;
11454
12174
  exports.getAuthLoading = getAuthLoading;
11455
12175
  exports.getAuthProvider = getAuthProvider;
11456
12176
  exports.getCurrentUser = getCurrentUser;
@@ -11460,6 +12180,7 @@ exports.getOrCreateTurnkeyWallet = getOrCreateTurnkeyWallet;
11460
12180
  exports.getPlatform = getPlatform;
11461
12181
  exports.getTurnkeyWalletRecoveryUrl = getTurnkeyWalletRecoveryUrl;
11462
12182
  exports.getTurnkeyWalletSessionState = getTurnkeyWalletSessionState;
12183
+ exports.getVenueEscrow = getVenueEscrow;
11463
12184
  exports.hasTurnkeyWallet = hasTurnkeyWallet;
11464
12185
  exports.init = init;
11465
12186
  exports.login = login;
@@ -11491,9 +12212,10 @@ exports.signSolanaMessageViaTurnkey = signSolanaMessageViaTurnkey;
11491
12212
  exports.signTransactionV1WithTurnkey = signTransactionV1WithTurnkey;
11492
12213
  exports.signTransactionWithTurnkey = signTransactionWithTurnkey;
11493
12214
  exports.startTurnkeyEmailLogin = startTurnkeyEmailLogin;
12215
+ exports.supportsWalletSignIn = supportsWalletSignIn;
11494
12216
  exports.transactionHasSignature = transactionHasSignature;
11495
12217
  exports.useAuth = useAuth;
11496
12218
  exports.useBuildRun = useBuildRun;
11497
12219
  exports.useQuery = useQuery;
11498
12220
  exports.waitForAuthReady = waitForAuthReady;
11499
- //# sourceMappingURL=index-BZ0X1Z9X.js.map
12221
+ //# sourceMappingURL=index-nU0ZSfWs.js.map