@bounded-sh/client 0.0.98 → 0.0.100-performance.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/auth/bounded-widget-modal.d.ts +7 -2
  2. package/dist/auth/oidc-auth.d.ts +1 -1
  3. package/dist/auth/session-provider.d.ts +1 -0
  4. package/dist/auth/turnkey-auth.d.ts +4 -1
  5. package/dist/auth/turnkey-signer-bridge.d.ts +8 -5
  6. package/dist/auth/turnkey-signer-frame.d.ts +4 -1
  7. package/dist/auth/turnkey-wallet-context.d.ts +24 -0
  8. package/dist/auth/turnkey-wallet-widget.d.ts +2 -0
  9. package/dist/builds/types.d.ts +31 -0
  10. package/dist/{email-auth-provider-DF7Urh8i.mjs → email-auth-provider-BGTfU1_i.mjs} +2 -2
  11. package/dist/{email-auth-provider-CiPAD3vz.mjs.map → email-auth-provider-BGTfU1_i.mjs.map} +1 -1
  12. package/dist/{email-auth-provider-DxB_pJKO.js → email-auth-provider-C6SFJd9L.js} +2 -2
  13. package/dist/{email-auth-provider-DxB_pJKO.js.map → email-auth-provider-C6SFJd9L.js.map} +1 -1
  14. package/dist/{email-auth-provider-CiPAD3vz.mjs → email-auth-provider-CIRbOSM3.mjs} +2 -2
  15. package/dist/{email-auth-provider-DF7Urh8i.mjs.map → email-auth-provider-CIRbOSM3.mjs.map} +1 -1
  16. package/dist/{email-auth-provider-BhYzRN0r.js → email-auth-provider-Cpj8hIFu.js} +2 -2
  17. package/dist/{email-auth-provider-BhYzRN0r.js.map → email-auth-provider-Cpj8hIFu.js.map} +1 -1
  18. package/dist/{guest-auth-provider-BiM35KHb.js → guest-auth-provider-0PjGFGDm.js} +2 -2
  19. package/dist/{guest-auth-provider-BiM35KHb.js.map → guest-auth-provider-0PjGFGDm.js.map} +1 -1
  20. package/dist/{guest-auth-provider-Dtsq4QaY.mjs → guest-auth-provider-C23vWrOT.mjs} +2 -2
  21. package/dist/{guest-auth-provider-DVw-tITC.mjs.map → guest-auth-provider-C23vWrOT.mjs.map} +1 -1
  22. package/dist/{guest-auth-provider-DVw-tITC.mjs → guest-auth-provider-DVxlea-z.mjs} +2 -2
  23. package/dist/{guest-auth-provider-Dtsq4QaY.mjs.map → guest-auth-provider-DVxlea-z.mjs.map} +1 -1
  24. package/dist/{guest-auth-provider-B9C3Iub_.js → guest-auth-provider-pC-AheTZ.js} +2 -2
  25. package/dist/{guest-auth-provider-B9C3Iub_.js.map → guest-auth-provider-pC-AheTZ.js.map} +1 -1
  26. package/dist/{index-CYdYsf8s.js → index-DUVRmF9-.js} +971 -606
  27. package/dist/index-DUVRmF9-.js.map +1 -0
  28. package/dist/{index-Cflemdaf.mjs → index-DmAXYXDi.mjs} +970 -607
  29. package/dist/index-DmAXYXDi.mjs.map +1 -0
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.js +3 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +1 -1
  34. package/dist/{index.native-BZOWS_sR.js → index.native-CllNqdoy.js} +442 -81
  35. package/dist/index.native-CllNqdoy.js.map +1 -0
  36. package/dist/{index.native-gVbAsohv.mjs → index.native-r1I-9E8e.mjs} +442 -81
  37. package/dist/index.native-r1I-9E8e.mjs.map +1 -0
  38. package/dist/index.native.js +1 -1
  39. package/dist/index.native.mjs +1 -1
  40. package/dist/{injected-evm-wallet-provider-CMqUqqxN.mjs → injected-evm-wallet-provider-BPZMEE8I.mjs} +2 -2
  41. package/dist/{injected-evm-wallet-provider-CMqUqqxN.mjs.map → injected-evm-wallet-provider-BPZMEE8I.mjs.map} +1 -1
  42. package/dist/{injected-evm-wallet-provider-C3MwUTRd.js → injected-evm-wallet-provider-BXM8TfS3.js} +2 -2
  43. package/dist/{injected-evm-wallet-provider-C3MwUTRd.js.map → injected-evm-wallet-provider-BXM8TfS3.js.map} +1 -1
  44. package/dist/{injected-evm-wallet-provider-K0j697jt.mjs → injected-evm-wallet-provider-CkhN5u3d.mjs} +2 -2
  45. package/dist/{injected-evm-wallet-provider-K0j697jt.mjs.map → injected-evm-wallet-provider-CkhN5u3d.mjs.map} +1 -1
  46. package/dist/{injected-evm-wallet-provider-Bv8VLuB1.js → injected-evm-wallet-provider-Dq3FDV1M.js} +2 -2
  47. package/dist/{injected-evm-wallet-provider-Bv8VLuB1.js.map → injected-evm-wallet-provider-Dq3FDV1M.js.map} +1 -1
  48. package/dist/{injected-wallet-provider-BDt4CN0b.js → injected-wallet-provider-B3LLEpfp.js} +2 -2
  49. package/dist/injected-wallet-provider-B3LLEpfp.js.map +1 -0
  50. package/dist/{injected-wallet-provider-CG3oKdp_.js → injected-wallet-provider-Bi_mB_q3.js} +2 -2
  51. package/dist/injected-wallet-provider-Bi_mB_q3.js.map +1 -0
  52. package/dist/{injected-wallet-provider-DH8yLpyf.mjs → injected-wallet-provider-BlSdRbgq.mjs} +2 -2
  53. package/dist/injected-wallet-provider-BlSdRbgq.mjs.map +1 -0
  54. package/dist/{injected-wallet-provider-Dlo96aV9.mjs → injected-wallet-provider-CLLhLBAJ.mjs} +2 -2
  55. package/dist/injected-wallet-provider-CLLhLBAJ.mjs.map +1 -0
  56. package/package.json +7 -3
  57. package/dist/bounded-widget-modal-C0Z7gmxH.mjs +0 -31
  58. package/dist/bounded-widget-modal-C0Z7gmxH.mjs.map +0 -1
  59. package/dist/bounded-widget-modal-s0PL86Y-.js +0 -33
  60. package/dist/bounded-widget-modal-s0PL86Y-.js.map +0 -1
  61. package/dist/index-CYdYsf8s.js.map +0 -1
  62. package/dist/index-Cflemdaf.mjs.map +0 -1
  63. package/dist/index.native-BZOWS_sR.js.map +0 -1
  64. package/dist/index.native-gVbAsohv.mjs.map +0 -1
  65. package/dist/injected-wallet-provider-BDt4CN0b.js.map +0 -1
  66. package/dist/injected-wallet-provider-CG3oKdp_.js.map +0 -1
  67. package/dist/injected-wallet-provider-DH8yLpyf.mjs.map +0 -1
  68. package/dist/injected-wallet-provider-Dlo96aV9.mjs.map +0 -1
@@ -1,6 +1,42 @@
1
1
  import { getConfig, getActiveSessionManager, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, reconnectWithNewAuth, onSessionCleared, deriveUserIdentityFromIdToken, subscribe, getFreshAuthToken, getSessionGeneration, getIdToken as getIdToken$1, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
2
2
  import * as React from 'react';
3
3
 
4
+ function walletContextFromClaims(claims, baseUrl, expectedAppId, tenantOrigin) {
5
+ const base = baseUrl.replace(/\/$/, '');
6
+ const scope = claims['custom:walletScope'];
7
+ const protocol = claims['custom:walletProtocol'];
8
+ if (scope !== undefined && scope !== 'legacy' && scope !== 'app')
9
+ throw new Error('wallet_scope_invalid');
10
+ if ((scope === 'app' && protocol !== 2) || (scope === 'legacy' && protocol !== 1)
11
+ || (scope === undefined && protocol !== undefined))
12
+ throw new Error('wallet_protocol_invalid');
13
+ const appId = claims['custom:appId'];
14
+ const userId = claims['custom:userId'];
15
+ const address = claims['custom:walletAddress'];
16
+ if (scope === 'app' && (appId !== expectedAppId || typeof appId !== 'string'
17
+ || !/^[a-f0-9]{24}$/.test(appId) || typeof userId !== 'string' || !userId
18
+ || claims.iss !== base))
19
+ throw new Error('wallet_session_context_invalid');
20
+ const resolvedScope = scope === 'app' ? 'app' : 'legacy';
21
+ const route = resolvedScope === 'app' ? `/wallet/turnkey/app/${appId}` : '/wallet/turnkey';
22
+ return {
23
+ scope: resolvedScope, appId: String(appId || expectedAppId), userId: String(userId || ''),
24
+ address: typeof address === 'string' ? address : '', base, origin: new URL(base).origin,
25
+ url: `${base}${route}/signer${resolvedScope === 'app' ? `?origin=${encodeURIComponent(tenantOrigin)}` : ''}`,
26
+ key: JSON.stringify([base, appId || expectedAppId, userId || '', address || '', resolvedScope]),
27
+ };
28
+ }
29
+ let loginGeneration = 0;
30
+ function invalidatePendingWalletLogin() { ++loginGeneration; }
31
+ function walletOperationGuard() {
32
+ const generation = loginGeneration;
33
+ return () => {
34
+ if (generation !== loginGeneration)
35
+ throw new Error('wallet_session_changed');
36
+ };
37
+ }
38
+ function setWalletSessionState(key, state) { }
39
+
4
40
  /**
5
41
  * Platform abstraction layer for React Native compatibility.
6
42
  *
@@ -944,7 +980,10 @@ function registerAuthRegistrySync(fn) {
944
980
  * Returns the normalized user published by this commit, or null when omitted.
945
981
  */
946
982
  async function adoptSessionProvider(opts) {
983
+ var _a;
947
984
  const coreConfig = await getConfig();
985
+ (_a = opts.beforeCommit) === null || _a === void 0 ? void 0 : _a.call(opts);
986
+ invalidatePendingWalletLogin();
948
987
  coreConfig.authProvider = opts.provider;
949
988
  coreConfig.authMethod = opts.method;
950
989
  setAuthProviderInstance(opts.provider);
@@ -4167,6 +4206,336 @@ async function ensureSolanaMobileWalletRegistered(config, network) {
4167
4206
 
4168
4207
  var bufferExports = requireBuffer();
4169
4208
 
4209
+ // bounded-widget-modal.ts - the shared in-app WIDGET shell for Bounded's login
4210
+ // and signing surfaces. One Shadow-DOM overlay + panel that matches the Bounded
4211
+ // widget (Seal) look and MOTION: a backdrop fade, a panel rise on desktop, a
4212
+ // bottom-sheet on mobile, a height tween as content swaps, and a clean close.
4213
+ //
4214
+ // It hosts EITHER:
4215
+ // - NATIVE content (the login card the SDK renders itself), or
4216
+ // - an IFRAME (the Bounded-owned signer page, which must run on the single
4217
+ // signer origin because the wallet's 24h signing session lives in that
4218
+ // origin's storage, out of every app's reach).
4219
+ //
4220
+ // The modal is a warm singleton: it stays mounted (hidden) between uses so a
4221
+ // second open - or a signature right after login - is instant and, when it is
4222
+ // already open, a clean in-place view swap rather than a reopen.
4223
+ function hasDOM$4() {
4224
+ return typeof window !== "undefined" && typeof document !== "undefined";
4225
+ }
4226
+ const OVERLAY_CSS = `
4227
+ :host{all:initial}
4228
+ *{box-sizing:border-box}
4229
+ .bw-ov{position:fixed;inset:0;z-index:2147483647;display:none;
4230
+ font-family:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif}
4231
+ .bw-ov.mounted{display:block}
4232
+ .bw-back{position:fixed;inset:0;background:rgba(4,4,5,.62);opacity:0;
4233
+ transition:opacity .24s ease;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}
4234
+ .bw-wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:20px}
4235
+ .bw-panel{position:relative;width:420px;max-width:calc(100vw - 28px);height:280px;
4236
+ border-radius:14px;overflow:hidden;background:#0e0f11;border:1px solid rgba(232,230,222,.08);
4237
+ box-shadow:0 1px 0 rgba(232,230,222,.03) inset,0 40px 90px -45px rgba(0,0,0,.85);
4238
+ opacity:0;transform:translateY(14px) scale(.98);will-change:transform,opacity,height;
4239
+ transition:opacity .28s cubic-bezier(.2,.8,.2,1),transform .28s cubic-bezier(.2,.8,.2,1),
4240
+ height .3s cubic-bezier(.2,.8,.2,1)}
4241
+ .bw-ov.show .bw-back{opacity:1}
4242
+ .bw-ov.show .bw-panel{opacity:1;transform:none}
4243
+ .bw-ov.closing .bw-back{opacity:0}
4244
+ .bw-ov.closing .bw-panel{opacity:0;transform:translateY(12px) scale(.99)}
4245
+ .bw-content{position:absolute;inset:0;overflow:hidden}
4246
+ .bw-frame{display:block;width:100%;height:100%;border:0;background:transparent;color-scheme:dark}
4247
+ /* editorial corner crop-marks, matching the reference frame */
4248
+ .bw-mk{position:absolute;width:13px;height:13px;pointer-events:none;z-index:2;
4249
+ border-color:rgba(232,230,222,.22);border-style:solid;border-width:0}
4250
+ .bw-mk.tl{top:11px;left:11px;border-top-width:1px;border-left-width:1px}
4251
+ .bw-mk.tr{top:11px;right:11px;border-top-width:1px;border-right-width:1px}
4252
+ .bw-mk.bl{bottom:11px;left:11px;border-bottom-width:1px;border-left-width:1px}
4253
+ .bw-mk.br{bottom:11px;right:11px;border-bottom-width:1px;border-right-width:1px}
4254
+ @media(max-width:560px){
4255
+ .bw-wrap{align-items:flex-end;padding:0}
4256
+ .bw-panel{width:100%;max-width:100%;border-radius:18px 18px 0 0;border-bottom:0}
4257
+ .bw-content{overflow-y:auto}
4258
+ .bw-ov.show .bw-panel{transform:none}
4259
+ .bw-ov:not(.show) .bw-panel,.bw-ov.closing .bw-panel{transform:translateY(18%)}
4260
+ }
4261
+ @media(prefers-reduced-motion:reduce){.bw-back,.bw-panel{transition:opacity .12s linear!important}}
4262
+ `;
4263
+ let modal = null;
4264
+ function getModal() {
4265
+ if (modal)
4266
+ return modal;
4267
+ const root = document.createElement("div");
4268
+ root.setAttribute("data-bounded-widget", "");
4269
+ const shadow = root.attachShadow({ mode: "open" });
4270
+ const style = document.createElement("style");
4271
+ style.textContent = OVERLAY_CSS;
4272
+ shadow.appendChild(style);
4273
+ const overlay = document.createElement("div");
4274
+ overlay.className = "bw-ov";
4275
+ const back = document.createElement("div");
4276
+ back.className = "bw-back";
4277
+ const wrap = document.createElement("div");
4278
+ wrap.className = "bw-wrap";
4279
+ const panel = document.createElement("div");
4280
+ panel.className = "bw-panel";
4281
+ const content = document.createElement("div");
4282
+ content.className = "bw-content";
4283
+ panel.appendChild(content);
4284
+ for (const corner of ["tl", "tr", "bl", "br"]) {
4285
+ const mk = document.createElement("span");
4286
+ mk.className = "bw-mk " + corner;
4287
+ panel.appendChild(mk);
4288
+ }
4289
+ wrap.appendChild(panel);
4290
+ overlay.appendChild(back);
4291
+ overlay.appendChild(wrap);
4292
+ shadow.appendChild(overlay);
4293
+ (document.body || document.documentElement).appendChild(root);
4294
+ const m = {
4295
+ root,
4296
+ overlay,
4297
+ panel,
4298
+ content,
4299
+ iframe: null,
4300
+ iframeOrigin: "",
4301
+ iframeReady: false,
4302
+ iframeContext: "",
4303
+ onBackdrop: null,
4304
+ onIframeMessage: null,
4305
+ chain: Promise.resolve(),
4306
+ fitObserver: null,
4307
+ generation: 0,
4308
+ onSupersede: null,
4309
+ };
4310
+ // The dismiss handler lives on `.bw-wrap`: it is the full-viewport flex layer
4311
+ // that sits ABOVE `.bw-back`, so it (not the backdrop element) receives clicks
4312
+ // outside the panel. Fire only when the click lands on the wrap itself, never
4313
+ // when it bubbles up from the panel or its content.
4314
+ wrap.addEventListener("click", (event) => {
4315
+ if (event.target === wrap && m.onBackdrop)
4316
+ m.onBackdrop();
4317
+ });
4318
+ window.addEventListener("message", (event) => {
4319
+ if (!m.iframe)
4320
+ return;
4321
+ if (event.origin !== m.iframeOrigin)
4322
+ return;
4323
+ if (event.source !== m.iframe.contentWindow)
4324
+ return;
4325
+ const d = event.data;
4326
+ if (!d || typeof d !== "object")
4327
+ return;
4328
+ // Readiness belongs to the document, even while login owns the modal and no
4329
+ // signing exchange is listening. The retained frame will not load again.
4330
+ if (d.type === "bounded:turnkey:ready")
4331
+ m.iframeReady = true;
4332
+ if (m.onIframeMessage)
4333
+ m.onIframeMessage(d);
4334
+ });
4335
+ modal = m;
4336
+ return m;
4337
+ }
4338
+ function showModal(m) {
4339
+ m.overlay.classList.remove("closing");
4340
+ m.overlay.classList.add("mounted");
4341
+ // Force a reflow so the .show transition runs from the hidden state every open.
4342
+ void m.panel.offsetWidth;
4343
+ m.overlay.classList.add("show");
4344
+ }
4345
+ function hideModal(m, after) {
4346
+ m.overlay.classList.remove("show");
4347
+ m.overlay.classList.add("closing");
4348
+ // Capture the generation at hide time. If a newer open re-shows the modal within
4349
+ // the close tween, this stale timer must NOT strip `.mounted`/`.closing` off the
4350
+ // freshly reopened widget - only tear down when we are still the same open.
4351
+ const gen = m.generation;
4352
+ window.setTimeout(() => {
4353
+ if (m.generation === gen)
4354
+ m.overlay.classList.remove("mounted", "closing");
4355
+ }, 260);
4356
+ }
4357
+ function setPanelHeight(m, px) {
4358
+ const h = Math.max(140, Math.min(680, Math.round(px)));
4359
+ m.panel.style.height = h + "px";
4360
+ }
4361
+ /** Get (or lazily create) the warm iframe for signer/hosted-page mode. */
4362
+ function ensureIframe(m, url, origin, context = "") {
4363
+ var _a;
4364
+ if (m.iframe && m.iframeOrigin === origin && m.iframe.src === url && m.iframeContext === context)
4365
+ return m.iframe;
4366
+ detachIframe(m);
4367
+ (_a = m.fitObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
4368
+ m.fitObserver = null;
4369
+ m.content.style.display = "none";
4370
+ const iframe = document.createElement("iframe");
4371
+ iframe.className = "bw-frame";
4372
+ iframe.setAttribute("title", "Bounded");
4373
+ iframe.setAttribute("allow", "clipboard-write");
4374
+ iframe.src = url;
4375
+ m.iframeOrigin = origin;
4376
+ m.iframeContext = context;
4377
+ m.iframeReady = false;
4378
+ m.panel.appendChild(iframe);
4379
+ m.iframe = iframe;
4380
+ return iframe;
4381
+ }
4382
+ /**
4383
+ * Destroy the warm signer iframe if one is currently mounted for `origin`, and report
4384
+ * whether there was one. Logout needs this: a signing session can live in that document's
4385
+ * MEMORY (the signer keeps an in-memory mirror when the browser blocks its storage), and a
4386
+ * throwaway iframe opened by the sweep can only ever clear the shared store, never another
4387
+ * document's memory. Removing the iframe discards its browsing context, which takes the
4388
+ * mirror with it.
4389
+ *
4390
+ * Deliberately does NOT call getModal(): that would BUILD a modal just to tear it down, on
4391
+ * every logout of every app, most of which never mounted one.
4392
+ */
4393
+ function detachWarmSignerIframe(origin) {
4394
+ if (!modal || !modal.iframe || (origin))
4395
+ return false;
4396
+ detachIframe(modal);
4397
+ return true;
4398
+ }
4399
+ function detachIframe(m) {
4400
+ if (m.iframe) {
4401
+ try {
4402
+ m.iframe.remove();
4403
+ }
4404
+ catch (_a) {
4405
+ /* ignore */
4406
+ }
4407
+ }
4408
+ m.iframe = null;
4409
+ m.iframeReady = false;
4410
+ m.iframeOrigin = "";
4411
+ m.iframeContext = "";
4412
+ m.onIframeMessage = null;
4413
+ }
4414
+
4415
+ // turnkey-wallet-widget.ts - runs one Turnkey signer exchange inside the shared
4416
+ // in-app WIDGET (bounded-widget-modal.ts). The Bounded-owned signer page is loaded
4417
+ // in a warm iframe behind the modal so signing feels native: an in-app approve
4418
+ // card (with inline code entry when the 24h signing session must first be
4419
+ // established), never a jarring popup.
4420
+ //
4421
+ // WHY AN IFRAME: the wallet's signing session lives in the single Bounded signer
4422
+ // origin's storage, out of every app's reach, so signing MUST run on that origin;
4423
+ // the iframe brings it in-app.
4424
+ //
4425
+ // Restricted embedders: if the frame never loads, the SAME request reruns through
4426
+ // `popupFallback` (a real window). Callers pass a popup implementation and never
4427
+ // see the difference.
4428
+ /**
4429
+ * Run one signer exchange through the in-app widget. Resolves when `onResult`
4430
+ * accepts a result; falls back to `popupFallback` if the frame cannot be mounted
4431
+ * or never loads.
4432
+ */
4433
+ async function runWidget(url, signerOrigin, ex, popupFallback) {
4434
+ if (!hasDOM$4())
4435
+ return popupFallback();
4436
+ const m = getModal();
4437
+ const requestId = String(ex.request.requestId);
4438
+ // Serialize: the approve card is modal, and one warm frame handles one request at a time.
4439
+ const run = m.chain.then(() => new Promise((resolve, reject) => {
4440
+ var _a;
4441
+ let settled = false;
4442
+ let usedFallback = false;
4443
+ (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
4444
+ const iframe = ensureIframe(m, url, signerOrigin, ex.context);
4445
+ const send = () => {
4446
+ var _a;
4447
+ if (!iframe.contentWindow)
4448
+ return;
4449
+ try {
4450
+ (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
4451
+ iframe.contentWindow.postMessage(ex.request, signerOrigin);
4452
+ }
4453
+ catch (_b) {
4454
+ finish(() => reject(new Error('wallet_session_changed')));
4455
+ }
4456
+ };
4457
+ let loadTimer = 0;
4458
+ let ceilingTimer = 0;
4459
+ const finish = (fn) => {
4460
+ if (settled)
4461
+ return;
4462
+ settled = true;
4463
+ m.onIframeMessage = null;
4464
+ m.onBackdrop = null;
4465
+ window.clearTimeout(loadTimer);
4466
+ window.clearTimeout(ceilingTimer);
4467
+ fn();
4468
+ };
4469
+ // The frame is WARM across exchanges, so an abandoned approval must be told to drop its
4470
+ // in-flight ceremony. Otherwise the signer keeps `approving` set for a card nobody is
4471
+ // looking at and refuses every later create/sign as `signer_request_superseded` (the
4472
+ // BSA-2026-012 guard) until the page reloads.
4473
+ const cancelInFrame = () => {
4474
+ if (!iframe.contentWindow)
4475
+ return;
4476
+ try {
4477
+ iframe.contentWindow.postMessage({ type: "bounded:turnkey:cancel", requestId }, signerOrigin);
4478
+ }
4479
+ catch (_a) {
4480
+ /* frame gone */
4481
+ }
4482
+ };
4483
+ const goFallback = () => {
4484
+ if (usedFallback || settled)
4485
+ return;
4486
+ usedFallback = true;
4487
+ hideModal(m);
4488
+ finish(() => popupFallback().then(resolve, reject));
4489
+ };
4490
+ m.onBackdrop = () => {
4491
+ cancelInFrame();
4492
+ hideModal(m);
4493
+ finish(() => reject(new Error("cancelled")));
4494
+ };
4495
+ m.onIframeMessage = (d) => {
4496
+ if (d.type === "bounded:turnkey:ready") {
4497
+ send();
4498
+ return;
4499
+ }
4500
+ if (d.type === "bounded:turnkey:resize" && typeof d.height === "number") {
4501
+ setPanelHeight(m, d.height);
4502
+ return;
4503
+ }
4504
+ if (d.type === "bounded:turnkey:result" && d.requestId === requestId) {
4505
+ const outcome = ex.onResult(d);
4506
+ if ("error" in outcome) {
4507
+ hideModal(m);
4508
+ finish(() => reject(new Error(outcome.error)));
4509
+ return;
4510
+ }
4511
+ if (outcome.done) {
4512
+ hideModal(m);
4513
+ finish(() => resolve(outcome.value));
4514
+ }
4515
+ }
4516
+ };
4517
+ showModal(m);
4518
+ if (m.iframeReady)
4519
+ send();
4520
+ // If the frame never loads, degrade to the popup (best-effort - a post-load
4521
+ // popup may be blocked without a gesture, in which case the fallback rejects).
4522
+ loadTimer = window.setTimeout(() => {
4523
+ if (!m.iframeReady && !settled)
4524
+ goFallback();
4525
+ }, 8000);
4526
+ // Absolute ceiling so a stuck flow cannot hang forever.
4527
+ ceilingTimer = window.setTimeout(() => {
4528
+ if (!settled) {
4529
+ cancelInFrame();
4530
+ hideModal(m);
4531
+ finish(() => reject(new Error("Wallet approval timed out.")));
4532
+ }
4533
+ }, 5 * 60 * 1000);
4534
+ }));
4535
+ m.chain = run.then(() => undefined, () => undefined);
4536
+ return run;
4537
+ }
4538
+
4170
4539
  // turnkey-signer-frame.ts - a HIDDEN, offscreen iframe of the Bounded signer page
4171
4540
  // for UI-less signer exchanges: sealing a login code (bounded:turnkey:encryptOtp),
4172
4541
  // establishing the 24h signing session right after login
@@ -4186,10 +4555,10 @@ async function signerPage() {
4186
4555
  return { url: `${base}/wallet/turnkey/signer`, origin: new URL(base).origin };
4187
4556
  }
4188
4557
  /** Mount the hidden signer frame. Callers MUST dispose() when done. */
4189
- async function openHiddenSignerFrame() {
4558
+ async function openHiddenSignerFrame(page) {
4190
4559
  if (!hasDOM$3())
4191
4560
  throw new Error('The Bounded signer frame is only available in the browser.');
4192
- const { url, origin } = await signerPage();
4561
+ const { url, origin } = page !== null && page !== void 0 ? page : await signerPage();
4193
4562
  const frame = document.createElement('iframe');
4194
4563
  frame.setAttribute('aria-hidden', 'true');
4195
4564
  frame.style.cssText =
@@ -4284,7 +4653,7 @@ async function requestTurnkeySigningCapability(opts) {
4284
4653
  res = await opts.fetchImpl(`${base}/wallet/turnkey/capability`, {
4285
4654
  method: 'POST',
4286
4655
  headers: { 'content-type': 'application/json' },
4287
- body: JSON.stringify({ idToken: opts.idToken, messageHex: opts.messageHex }),
4656
+ body: JSON.stringify({ idToken: opts.idToken, messageHex: opts.messageHex, walletProtocol: 2 }),
4288
4657
  });
4289
4658
  }
4290
4659
  catch (_a) {
@@ -4336,7 +4705,7 @@ async function requestTurnkeyActionAuthorization(opts) {
4336
4705
  res = await opts.fetchImpl(`${base}/wallet/turnkey/action-authorization`, {
4337
4706
  method: 'POST',
4338
4707
  headers: { 'content-type': 'application/json' },
4339
- body: JSON.stringify({ idToken: opts.idToken, action: opts.action }),
4708
+ body: JSON.stringify({ idToken: opts.idToken, action: opts.action, walletProtocol: 2 }),
4340
4709
  });
4341
4710
  }
4342
4711
  catch (_a) {
@@ -4376,26 +4745,39 @@ async function requestTurnkeyActionAuthorization(opts) {
4376
4745
  // code is the sole signing authority; within a live session every signature is one
4377
4746
  // approval click). The app retains the transaction itself.
4378
4747
  //
4379
- // ONE ORIGIN, ONE SESSION: the signing session lives in the signer origin's own
4380
- // storage, out of every app's reach, so ALL Bounded apps (any subdomain / custom
4381
- // domain) sign through this one origin - giving every user one wallet that roams
4382
- // across every app.
4748
+ // Signing keys remain on the trusted signer origin. New apps use independently
4749
+ // bound wallets and storage slots; legacy apps retain their shared wallet.
4383
4750
  function hasDOM$2() {
4384
4751
  return typeof window !== 'undefined' && typeof document !== 'undefined';
4385
4752
  }
4386
- // BSA-2026-006: dispatch every signing / get-or-create exchange through a TOP-LEVEL
4387
- // POPUP the caller opened from the user gesture - NEVER a framed widget. An authorized
4388
- // tenant that embedded the signer could overlay its predictable Approve control and steal
4389
- // one concealed click into a fund-moving signature; a top-level window it cannot reach or
4390
- // visually redress closes that. A blocked popup surfaces `popup_blocked` (runPopup) and we
4391
- // never silently fall back to an iframe.
4753
+ // Dispatch one signer exchange through the in-app WIDGET, degrading to the POPUP
4754
+ // when we cannot embed (no DOM, or the frame never mounts/loads). Nothing in the
4755
+ // email-session flow needs a popup by preference: the code entry and the approval
4756
+ // click both run fine inside a cross-origin iframe on every engine (the old
4757
+ // Safari popup preference existed only for in-iframe WebAuthn CREATE).
4392
4758
  async function deliver(url, origin, ex) {
4393
- return runPopup(url, origin, ex);
4394
- }
4395
- async function turnkeySignerPage() {
4759
+ var _a, _b;
4760
+ const popup = () => runPopup(url, origin, ex);
4761
+ (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
4762
+ const result = await runWidget(url, origin, { request: ex.request, onResult: ex.onResult, context: ex.context, assertCurrent: ex.assertCurrent }, popup);
4763
+ (_b = ex.assertCurrent) === null || _b === void 0 ? void 0 : _b.call(ex);
4764
+ return result;
4765
+ }
4766
+ async function turnkeySignerPage(token) {
4767
+ const assertGeneration = walletOperationGuard();
4768
+ const idToken = token === undefined ? getActiveSessionManager().getIdToken() : token;
4396
4769
  const cfg = await getConfig();
4397
4770
  const base = (cfg.humanAuthApiUrl || 'https://auth.bounded.sh').replace(/\/$/, '');
4398
- return { url: `${base}/wallet/turnkey/signer`, origin: new URL(base).origin };
4771
+ const context = walletContextFromClaims(idToken ? decodeJwt$1(idToken) : {}, base, cfg.appId, window.location.origin);
4772
+ return Object.assign(Object.assign({}, context), { idToken: idToken || '', assertCurrent() {
4773
+ assertGeneration();
4774
+ const current = getActiveSessionManager().getIdToken();
4775
+ if (!current)
4776
+ throw new Error('wallet_session_changed');
4777
+ const next = walletContextFromClaims(decodeJwt$1(current), base, cfg.appId, window.location.origin);
4778
+ if (next.key !== context.key)
4779
+ throw new Error('wallet_session_changed');
4780
+ } });
4399
4781
  }
4400
4782
  function toHex(bytes) {
4401
4783
  let h = '';
@@ -4451,7 +4833,7 @@ async function runPopup(url, signerOrigin, ex) {
4451
4833
  const top = window.screenY + Math.max(0, (window.outerHeight - h) / 2);
4452
4834
  const popup = window.open(url, 'bounded-turnkey-signer', `width=${w},height=${h},left=${left},top=${top}`);
4453
4835
  if (!popup) {
4454
- throw new Error('popup_blocked - the wallet approval window was blocked. Call this from a user gesture (e.g. a click handler) so it can open; we never fall back to an in-page frame.');
4836
+ throw new Error('Popup blocked - call this from a user gesture (e.g. a click handler) so the wallet approval window can open.');
4455
4837
  }
4456
4838
  return await new Promise((resolve, reject) => {
4457
4839
  let settled = false;
@@ -4467,11 +4849,12 @@ async function runPopup(url, signerOrigin, ex) {
4467
4849
  let closeTimer;
4468
4850
  const cleanup = () => { settled = true; window.removeEventListener('message', onMsg); if (closeTimer)
4469
4851
  clearInterval(closeTimer); };
4470
- const sendRequest = () => { if (settled || acked)
4852
+ const sendRequest = () => { var _a; if (settled || acked)
4471
4853
  return; try {
4854
+ (_a = ex.assertCurrent) === null || _a === void 0 ? void 0 : _a.call(ex);
4472
4855
  popup.postMessage(ex.request, signerOrigin);
4473
4856
  }
4474
- catch ( /* popup gone */_a) { /* popup gone */ } };
4857
+ catch ( /* popup gone */_b) { /* popup gone */ } };
4475
4858
  const onMsg = (event) => {
4476
4859
  if (event.origin !== signerOrigin)
4477
4860
  return;
@@ -4541,16 +4924,9 @@ async function runPopup(url, signerOrigin, ex) {
4541
4924
  // identity with the Bounded id token WE minted (a body secret, RS256-verified server-side), not
4542
4925
  // an ambient cookie - the issuer's session cookie is SameSite-scoped to its own origin and is
4543
4926
  // not sent on this cross-origin fetch, so the token is what carries the session's wallet.
4544
- async function fetchSigningCapability(messageHex) {
4545
- const cfg = await getConfig();
4546
- const base = (cfg.humanAuthApiUrl || 'https://auth.bounded.sh').replace(/\/$/, '');
4547
- let idToken = null;
4548
- try {
4549
- idToken = getActiveSessionManager().getIdToken();
4550
- }
4551
- catch (_a) {
4552
- idToken = null;
4553
- }
4927
+ async function fetchSigningCapability(messageHex, context) {
4928
+ context.assertCurrent();
4929
+ const { base, idToken } = context;
4554
4930
  if (!idToken) {
4555
4931
  throw new Error('This session has no Turnkey wallet. Sign in again to provision one.');
4556
4932
  }
@@ -4565,16 +4941,9 @@ async function fetchSigningCapability(messageHex) {
4565
4941
  // requires an issuer-signed authorization bound to this app origin and exact action. Fetch it
4566
4942
  // before posting to the signer. Walletless sessions are valid for createWallet because that is
4567
4943
  // the operation that provisions their first wallet.
4568
- async function fetchActionAuthorization(action) {
4569
- const cfg = await getConfig();
4570
- const base = (cfg.humanAuthApiUrl || 'https://auth.bounded.sh').replace(/\/$/, '');
4571
- let idToken = null;
4572
- try {
4573
- idToken = getActiveSessionManager().getIdToken();
4574
- }
4575
- catch (_a) {
4576
- idToken = null;
4577
- }
4944
+ async function fetchActionAuthorization(action, context) {
4945
+ context.assertCurrent();
4946
+ const { base, idToken } = context;
4578
4947
  if (!idToken) {
4579
4948
  throw new Error('Sign in again to set up your Turnkey wallet.');
4580
4949
  }
@@ -4594,31 +4963,23 @@ async function fetchActionAuthorization(action) {
4594
4963
  * an unswept session is account-bound and unusable without a live authorization,
4595
4964
  * it just costs its owner nothing and a stranger nothing.
4596
4965
  */
4597
- async function clearTurnkeySigningSession() {
4966
+ async function clearTurnkeySigningSession(idToken) {
4598
4967
  if (!hasDOM$2())
4599
4968
  return;
4600
- // The session can live in TWO places, and the sweep has to reach both:
4601
- // 1. the signer origin's store, shared by every signer frame in this app's partition -
4602
- // cleared by posting into a throwaway frame below;
4603
- // 2. the WARM widget iframe's memory. The signer keeps an in-memory mirror when the
4604
- // browser blocks its storage, and hideModal deliberately leaves that iframe mounted
4605
- // between signatures, so the mirror outlives logout. A throwaway frame cannot see
4606
- // another document's memory - the only way to take it is to destroy that document.
4607
- // Done first, and synchronously, so it lands even if the frame exchange below fails.
4608
- try {
4609
- const { origin } = await turnkeySignerPage();
4610
- (await import('./bounded-widget-modal-C0Z7gmxH.mjs')).detachWarmSignerIframe(origin);
4611
- }
4612
- catch (_a) {
4613
- /* no modal module / no warm frame: nothing to take */
4614
- }
4969
+ // Destroy the trusted in-memory key even if configuration or token parsing fails.
4970
+ // Do it synchronously, before a different login can mount a replacement frame.
4971
+ detachWarmSignerIframe();
4972
+ // Capture the session before asynchronous teardown clears the SDK's token.
4973
+ const contextPromise = turnkeySignerPage(idToken);
4615
4974
  let frame = null;
4616
4975
  try {
4617
- frame = await openHiddenSignerFrame();
4976
+ const context = await contextPromise;
4977
+ setWalletSessionState(context.key, { status: 'verification-required', reason: 'logged_out' });
4978
+ frame = await openHiddenSignerFrame(context);
4618
4979
  await frame.request({ type: 'bounded:turnkey:clearSigningSession', requestId: `tkclear_${Date.now()}_${++requestSeq}` }, 4000);
4619
4980
  }
4620
- catch (_b) {
4621
- /* best-effort: never block or fail logout on the sweep */
4981
+ catch (_a) {
4982
+ // The warm frame was destroyed; the bounded store sweep is best effort.
4622
4983
  }
4623
4984
  finally {
4624
4985
  frame === null || frame === void 0 ? void 0 : frame.dispose();
@@ -4628,10 +4989,9 @@ function hasTurnkeyWallet() {
4628
4989
  return activeTurnkeyAddress() !== null;
4629
4990
  }
4630
4991
  /**
4631
- * Open the Bounded Turnkey signer popup and sign `message` (raw bytes) with the
4632
- * user's non-custodial Turnkey wallet, resolving with the ed25519 signature +
4633
- * the wallet address. MUST be called from a USER GESTURE (click/tap) or the
4634
- * browser blocks the popup.
4992
+ * Open the Bounded Turnkey approval card and sign `message` (raw bytes) with the
4993
+ * user's Turnkey wallet, resolving with the ed25519 signature and wallet address.
4994
+ * Call from a user gesture so a deliberate browser fallback can open if needed.
4635
4995
  *
4636
4996
  * The signer shows an approve card (wallet address, requesting origin, Approve /
4637
4997
  * Cancel). With a live 24-hour signing session (normally established by the login
@@ -4641,23 +5001,26 @@ function hasTurnkeyWallet() {
4641
5001
  */
4642
5002
  async function signSolanaMessageViaTurnkey(message) {
4643
5003
  if (!hasDOM$2()) {
4644
- throw new Error('Turnkey embedded-wallet signing is only available in the browser (popup-based).');
5004
+ throw new Error('Turnkey embedded-wallet signing is only available in the browser (trusted wallet UI).');
4645
5005
  }
4646
- const { url, origin } = await turnkeySignerPage();
5006
+ const context = await turnkeySignerPage();
5007
+ const { url, origin } = context;
4647
5008
  const requestId = `tksign_${Date.now()}_${++requestSeq}`;
4648
5009
  const messageHex = toHex(message);
4649
5010
  // AS-02: obtain the issuer-signed capability for THESE exact bytes first; the signer will
4650
5011
  // refuse (capability_required) without it. Fetched per signature (each is single-payload).
4651
- const capability = await fetchSigningCapability(messageHex);
5012
+ const capability = await fetchSigningCapability(messageHex, context);
4652
5013
  // Inline (authMode:"turnkey") sessions plant no Better Auth cookie on the issuer, so the
4653
5014
  // signer's same-origin status/create fetches need a bearer session proof: attach the
4654
5015
  // createWallet action authorization (it covers the sign flow's get-or-create too). Minted
4655
5016
  // from the same id token as the capability, so a session that minted one can mint both.
4656
- const authorization = await fetchActionAuthorization('createWallet');
5017
+ const authorization = await fetchActionAuthorization('createWallet', context);
4657
5018
  return await deliver(url, origin, {
5019
+ context: context.key, assertCurrent: context.assertCurrent,
4658
5020
  request: buildTurnkeySignRequest({ requestId, messageHex, capability, authorization }),
4659
5021
  onResult: (d) => {
4660
5022
  if (d.ok && typeof d.signatureHex === 'string' && typeof d.address === 'string') {
5023
+ setWalletSessionState(context.key, { expiresAt: Number(d.signingSessionExpiresAt) });
4661
5024
  return { done: true, value: { signature: fromHex(d.signatureHex), address: d.address, subOrgId: String(d.subOrgId || '') } };
4662
5025
  }
4663
5026
  return { error: String(d.error || 'Turnkey signing failed') };
@@ -5342,9 +5705,6 @@ async function exchangeCode(code, verifier, redirectUri) {
5342
5705
  return user;
5343
5706
  }
5344
5707
 
5345
- // NOTE: Provider class re-exports have been moved to index.ts (web) and
5346
- // index.native.ts (RN) to avoid eager resolution of web-only dependencies
5347
- // (react-dom) when this module is imported on RN.
5348
5708
  let currentAuthProvider = null;
5349
5709
  let currentAuthMethod = null;
5350
5710
  let currentAuthProviderConfigKey = null;
@@ -5684,7 +6044,7 @@ async function getAuthProvider(config) {
5684
6044
  // manager as legacy email sessions. Human login should be started
5685
6045
  // with loginWithRedirect(); this provider is kept as the restore and
5686
6046
  // logout surface for those sessions.
5687
- currentAuthProvider = new (await import('./email-auth-provider-CiPAD3vz.mjs')).EmailAuthProvider();
6047
+ currentAuthProvider = new (await import('./email-auth-provider-CIRbOSM3.mjs')).EmailAuthProvider();
5688
6048
  break;
5689
6049
  case "phantom": {
5690
6050
  // First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
@@ -5726,7 +6086,7 @@ async function getAuthProvider(config) {
5726
6086
  // (bounded-login-widget.ts), so registration never counts as
5727
6087
  // evidence the user has a wallet.
5728
6088
  await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
5729
- const { InjectedWalletProvider } = await import('./injected-wallet-provider-DH8yLpyf.mjs');
6089
+ const { InjectedWalletProvider } = await import('./injected-wallet-provider-BlSdRbgq.mjs');
5730
6090
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
5731
6091
  break;
5732
6092
  }
@@ -5739,7 +6099,7 @@ async function getAuthProvider(config) {
5739
6099
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
5740
6100
  // to point at a specific wallet or set chainId/domain.
5741
6101
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
5742
- const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-K0j697jt.mjs');
6102
+ const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-CkhN5u3d.mjs');
5743
6103
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
5744
6104
  break;
5745
6105
  }
@@ -5764,7 +6124,7 @@ async function getAuthProvider(config) {
5764
6124
  break;
5765
6125
  case "guest":
5766
6126
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
5767
- currentAuthProvider = new (await import('./guest-auth-provider-Dtsq4QaY.mjs')).GuestAuthProvider();
6127
+ currentAuthProvider = new (await import('./guest-auth-provider-C23vWrOT.mjs')).GuestAuthProvider();
5768
6128
  break;
5769
6129
  }
5770
6130
  if (!currentAuthProvider) {
@@ -5826,7 +6186,7 @@ async function signInAnonymously() {
5826
6186
  // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
5827
6187
  // the main bundle for data-only apps. Specifier is a static string literal
5828
6188
  // so bundle-splitting can see it.
5829
- const provider = new (await import('./guest-auth-provider-Dtsq4QaY.mjs')).GuestAuthProvider();
6189
+ const provider = new (await import('./guest-auth-provider-C23vWrOT.mjs')).GuestAuthProvider();
5830
6190
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
5831
6191
  // adoptSessionProvider awaits only getConfig() (already resolved here) and then
5832
6192
  // runs every write - provider/method/config/marker/user - in one synchronous
@@ -5997,7 +6357,7 @@ function ensureSharedWalletLoginReady() {
5997
6357
  if (!sharedWalletReady) {
5998
6358
  sharedWalletReady = (async () => {
5999
6359
  await getConfig();
6000
- await import('./injected-wallet-provider-DH8yLpyf.mjs');
6360
+ await import('./injected-wallet-provider-BlSdRbgq.mjs');
6001
6361
  })().catch((error) => {
6002
6362
  sharedWalletReady = null;
6003
6363
  throw error;
@@ -6134,13 +6494,14 @@ async function exchangeLogoutHint(issuerBase, idToken) {
6134
6494
  // which can be blocked or offline), so its failures are the one thing logout may
6135
6495
  // tolerate - never revokeSession's. Lazy import per this module's rule (the signer
6136
6496
  // bridge is browser-only machinery). Never rejects.
6137
- async function sweepTurnkeySigningSession() {
6497
+ async function sweepTurnkeySigningSession(idToken) {
6138
6498
  try {
6139
- await (await Promise.resolve().then(function () { return turnkeySignerBridge; })).clearTurnkeySigningSession();
6499
+ await (await Promise.resolve().then(function () { return turnkeySignerBridge; })).clearTurnkeySigningSession(idToken);
6140
6500
  }
6141
6501
  catch ( /* best-effort: never block or fail logout on the sweep */_a) { /* best-effort: never block or fail logout on the sweep */ }
6142
6502
  }
6143
6503
  async function logout$1(options) {
6504
+ invalidatePendingWalletLogin();
6144
6505
  // Re-initialize the provider if it was cleared by a prior logout — the exact mirror
6145
6506
  // of login()'s self-heal above. Every session-establishment path now adopts through
6146
6507
  // session-provider.ts, so this is a REPAIR (the registry was cleared by a previous
@@ -6172,7 +6533,7 @@ async function logout$1(options) {
6172
6533
  // sweep is a hidden signer-iframe exchange; start it now (after revocation is
6173
6534
  // committed - a failed logout leaves the still-logged-in user their session) and
6174
6535
  // let it overlap the provider teardown. sweepTurnkeySigningSession never rejects.
6175
- const signingSessionSweep = sweepTurnkeySigningSession();
6536
+ const signingSessionSweep = sweepTurnkeySigningSession(idTokenHint);
6176
6537
  // Only OIDC-hosted sessions own an issuer browser cookie. Turnkey-native
6177
6538
  // email OTP is also an email auth method, but it mints the app session
6178
6539
  // inline and has no issuer cookie to clear. Use the explicit session-kind
@@ -7964,4 +8325,4 @@ class PrivyExpoProvider {
7964
8325
  }
7965
8326
 
7966
8327
  export { BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as $, logout as A, getAuthProvider as B, signInAnonymously as C, loginWithPrivy as D, loginWithRedirect as E, completeLoginFromRedirect as F, loginWithPopup as G, completeLoginInPopup as H, useAuth as I, useQuery as J, useBuildRun as K, apps as L, getIdToken as M, onramp as N, onrampQuote as O, onrampStatus as P, setPlatform as Q, OffchainAuthProvider as R, PrivyExpoProvider as S, builds as T, BuildsApiError as U, NON_TERMINAL_STATES as V, TERMINAL_STATES as W, RUN_STATES as X, PARK_REASONS as Y, FAILURE_REASONS as Z, BUILD_REVIEW_CAPABILITY_SCHEMA as _, signMessageWithTurnkey as a, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as a0, signTransactionWithTurnkey as b, signTransactionV1WithTurnkey as c, signAndSubmitTransactionWithTurnkey as d, bs58 as e, getWallets as f, getPlatform as g, hasTurnkeyWallet as h, isSolanaMobileWallet as i, solanaMobileWalletLeavesPage as j, setAuthLoading as k, bufferExports as l, setStoredAuthMethod as m, normalizeSolanaRpcUrl as n, confirmAndCheckTransaction as o, resolveSolanaRpcUrl as p, init as q, resolveSolanaWalletStandardChain as r, setCurrentUser as s, transactionHasSignature as t, getCurrentUser as u, onAuthStateChanged as v, onAuthLoadingChanged as w, getAuthLoading as x, waitForAuthReady as y, login as z };
7967
- //# sourceMappingURL=index.native-gVbAsohv.mjs.map
8328
+ //# sourceMappingURL=index.native-r1I-9E8e.mjs.map