@bounded-sh/client 0.0.59 → 0.0.61

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 (54) hide show
  1. package/dist/{email-auth-provider-N-dfsNnE.js → email-auth-provider-9BwSziWj.js} +2 -2
  2. package/dist/{email-auth-provider-N-dfsNnE.js.map → email-auth-provider-9BwSziWj.js.map} +1 -1
  3. package/dist/{email-auth-provider-DhAMOILG.mjs → email-auth-provider-B3XaJw-G.mjs} +2 -2
  4. package/dist/{email-auth-provider-deB_ADc5.mjs.map → email-auth-provider-B3XaJw-G.mjs.map} +1 -1
  5. package/dist/{email-auth-provider-BSw9FRjg.js → email-auth-provider-BttT2sZK.js} +2 -2
  6. package/dist/{email-auth-provider-BSw9FRjg.js.map → email-auth-provider-BttT2sZK.js.map} +1 -1
  7. package/dist/{email-auth-provider-deB_ADc5.mjs → email-auth-provider-Cb4VKA1E.mjs} +2 -2
  8. package/dist/{email-auth-provider-DhAMOILG.mjs.map → email-auth-provider-Cb4VKA1E.mjs.map} +1 -1
  9. package/dist/{guest-auth-provider-D9wbogwi.mjs → guest-auth-provider-BBPpydtM.mjs} +2 -2
  10. package/dist/{guest-auth-provider-B78Ugfar.mjs.map → guest-auth-provider-BBPpydtM.mjs.map} +1 -1
  11. package/dist/{guest-auth-provider-B78Ugfar.mjs → guest-auth-provider-BBSFawAr.mjs} +2 -2
  12. package/dist/{guest-auth-provider-D9wbogwi.mjs.map → guest-auth-provider-BBSFawAr.mjs.map} +1 -1
  13. package/dist/{guest-auth-provider-Czl48mOP.js → guest-auth-provider-BcR-MQ0g.js} +2 -2
  14. package/dist/{guest-auth-provider-Czl48mOP.js.map → guest-auth-provider-BcR-MQ0g.js.map} +1 -1
  15. package/dist/{guest-auth-provider-BFodq9Rc.js → guest-auth-provider-Di0TRg-z.js} +2 -2
  16. package/dist/{guest-auth-provider-BFodq9Rc.js.map → guest-auth-provider-Di0TRg-z.js.map} +1 -1
  17. package/dist/{index-uu8hKP-p.js → index-C_L497w1.js} +191 -51
  18. package/dist/index-C_L497w1.js.map +1 -0
  19. package/dist/{index-SHt4VZZV.mjs → index-L2R6C5Vl.mjs} +190 -52
  20. package/dist/index-L2R6C5Vl.mjs.map +1 -0
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +3 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +1 -1
  25. package/dist/{index.native-D-8IAEy-.mjs → index.native-BIUs8t7F.mjs} +182 -51
  26. package/dist/index.native-BIUs8t7F.mjs.map +1 -0
  27. package/dist/{index.native-D48QQ0-q.js → index.native-BSheiGj2.js} +183 -50
  28. package/dist/index.native-BSheiGj2.js.map +1 -0
  29. package/dist/index.native.d.ts +2 -2
  30. package/dist/index.native.js +3 -1
  31. package/dist/index.native.js.map +1 -1
  32. package/dist/index.native.mjs +1 -1
  33. package/dist/{injected-evm-wallet-provider-HQMOL_mZ.js → injected-evm-wallet-provider-7XawIUdJ.js} +2 -2
  34. package/dist/{injected-evm-wallet-provider-HQMOL_mZ.js.map → injected-evm-wallet-provider-7XawIUdJ.js.map} +1 -1
  35. package/dist/{injected-evm-wallet-provider-UWvcy-LO.mjs → injected-evm-wallet-provider-DSFDC8fh.mjs} +2 -2
  36. package/dist/{injected-evm-wallet-provider-UWvcy-LO.mjs.map → injected-evm-wallet-provider-DSFDC8fh.mjs.map} +1 -1
  37. package/dist/{injected-evm-wallet-provider-CItxws1D.js → injected-evm-wallet-provider-DgWUaVtt.js} +2 -2
  38. package/dist/{injected-evm-wallet-provider-CItxws1D.js.map → injected-evm-wallet-provider-DgWUaVtt.js.map} +1 -1
  39. package/dist/{injected-evm-wallet-provider-CJsLX16m.mjs → injected-evm-wallet-provider-DnOrVMDX.mjs} +2 -2
  40. package/dist/{injected-evm-wallet-provider-CJsLX16m.mjs.map → injected-evm-wallet-provider-DnOrVMDX.mjs.map} +1 -1
  41. package/dist/{injected-wallet-provider-CmXqreEE.js → injected-wallet-provider-BMDJntMD.js} +2 -2
  42. package/dist/{injected-wallet-provider-CmXqreEE.js.map → injected-wallet-provider-BMDJntMD.js.map} +1 -1
  43. package/dist/{injected-wallet-provider-BihII94U.mjs → injected-wallet-provider-DfJvN3sV.mjs} +2 -2
  44. package/dist/{injected-wallet-provider-BihII94U.mjs.map → injected-wallet-provider-DfJvN3sV.mjs.map} +1 -1
  45. package/dist/{injected-wallet-provider-CNYAynIB.mjs → injected-wallet-provider-ZkPzVj5W.mjs} +2 -2
  46. package/dist/{injected-wallet-provider-CNYAynIB.mjs.map → injected-wallet-provider-ZkPzVj5W.mjs.map} +1 -1
  47. package/dist/{injected-wallet-provider-CVeZgfEt.js → injected-wallet-provider-oCRGuls5.js} +2 -2
  48. package/dist/{injected-wallet-provider-CVeZgfEt.js.map → injected-wallet-provider-oCRGuls5.js.map} +1 -1
  49. package/dist/onramp.d.ts +51 -9
  50. package/package.json +2 -2
  51. package/dist/index-SHt4VZZV.mjs.map +0 -1
  52. package/dist/index-uu8hKP-p.js.map +0 -1
  53. package/dist/index.native-D-8IAEy-.mjs.map +0 -1
  54. package/dist/index.native-D48QQ0-q.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@bounded-sh/core');
4
- var index = require('./index-uu8hKP-p.js');
4
+ var index = require('./index-C_L497w1.js');
5
5
  require('react');
6
6
 
7
7
  // guest-keystore.ts — durable per-device keypair for anonymous ("guest") auth.
@@ -274,4 +274,4 @@ class GuestAuthProvider {
274
274
  }
275
275
 
276
276
  exports.GuestAuthProvider = GuestAuthProvider;
277
- //# sourceMappingURL=guest-auth-provider-BFodq9Rc.js.map
277
+ //# sourceMappingURL=guest-auth-provider-Di0TRg-z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guest-auth-provider-BFodq9Rc.js","sources":["../.rollup-tmp/auth/providers/guest-keystore.js","../.rollup-tmp/auth/providers/guest-auth-provider.js"],"sourcesContent":["// guest-keystore.ts — durable per-device keypair for anonymous (\"guest\") auth.\n//\n// A guest is an ed25519 keypair generated on the device. Its public key is the\n// Bounded account address; it signs the auth challenge exactly like a wallet.\n//\n// Guest auth has one backend: WebCrypto Ed25519 + IndexedDB. The key is\n// NON-EXTRACTABLE: an XSS can ask it to sign but can never read the private\n// bytes. If WebCrypto or IndexedDB is unavailable, guest auth fails closed\n// instead of silently creating an extractable/stored-secret credential.\n//\n// The public output is a base58 address + a base64\n// detached signature, which is the format the session endpoint already accepts.\nimport bs58 from 'bs58';\nimport { getPlatform } from '../../platform';\nconst LEGACY_STORED_SECRET_KEY = 'bounded_guest_key_v1';\nconst IDB_NAME = 'bounded-guest';\nconst IDB_STORE = 'keys';\nconst IDB_KEY = 'ed25519';\nconst GUEST_KEY_REQUIREMENT = 'Guest auth requires non-extractable WebCrypto Ed25519 keys persisted in IndexedDB; ' +\n 'stored-secret guest credentials are disabled.';\nfunction toBase64(bytes) {\n let bin = '';\n for (let i = 0; i < bytes.length; i++)\n bin += String.fromCharCode(bytes[i]);\n // btoa exists in browsers + RN (Hermes) ; Buffer is the Node/SSR fallback.\n return typeof btoa !== 'undefined' ? btoa(bin) : Buffer.from(bytes).toString('base64');\n}\n// ----- WebCrypto (non-extractable) backend -----------------------------------\nfunction subtle() {\n const c = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto;\n return c && c.subtle ? c.subtle : null;\n}\nfunction idb() {\n return new Promise((resolve, reject) => {\n const req = globalThis.indexedDB.open(IDB_NAME, 1);\n req.onupgradeneeded = () => req.result.createObjectStore(IDB_STORE);\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\nfunction idbGet(db, key) {\n return new Promise((resolve, reject) => {\n const r = db.transaction(IDB_STORE, 'readonly').objectStore(IDB_STORE).get(key);\n r.onsuccess = () => resolve(r.result);\n r.onerror = () => reject(r.error);\n });\n}\nfunction idbPut(db, key, val) {\n return new Promise((resolve, reject) => {\n const r = db.transaction(IDB_STORE, 'readwrite').objectStore(IDB_STORE).put(val, key);\n r.onsuccess = () => resolve();\n r.onerror = () => reject(r.error);\n });\n}\nfunction guestKeyUnavailable(cause) {\n const detail = cause instanceof Error && cause.message ? ` Cause: ${cause.message}` : '';\n return new Error(`${GUEST_KEY_REQUIREMENT}${detail}`);\n}\nasync function webCryptoKey(createIfMissing) {\n const s = subtle();\n if (!s)\n throw guestKeyUnavailable(new Error('WebCrypto subtle crypto is unavailable.'));\n if (typeof globalThis.indexedDB === 'undefined') {\n throw guestKeyUnavailable(new Error('IndexedDB is unavailable.'));\n }\n try {\n const db = await idb();\n let pair = (await idbGet(db, IDB_KEY));\n if (!pair) {\n if (!createIfMissing)\n return null;\n // Probe Ed25519 support by generating (throws on unsupported engines).\n pair = (await s.generateKey({ name: 'Ed25519' }, /* extractable */ false, [\n 'sign',\n 'verify',\n ]));\n await idbPut(db, IDB_KEY, pair); // CryptoKey is structured-cloneable; bytes never exposed\n }\n const raw = new Uint8Array(await s.exportKey('raw', pair.publicKey)); // public is exportable\n const address = bs58.encode(raw);\n return {\n address,\n nonExtractable: true,\n async sign(message) {\n const data = new TextEncoder().encode(message);\n const sig = new Uint8Array(await s.sign({ name: 'Ed25519' }, pair.privateKey, data));\n return toBase64(sig);\n },\n };\n }\n catch (error) {\n throw guestKeyUnavailable(error);\n }\n}\nlet cached = null;\n/** Get (or create) this device's durable guest key. */\nexport async function getGuestKey() {\n if (cached)\n return cached;\n cached = await webCryptoKey(true);\n if (!cached)\n throw guestKeyUnavailable(new Error('Guest key creation returned no key.'));\n return cached;\n}\n/** Read the existing durable guest key without ever minting a replacement. */\nexport async function getExistingGuestKey() {\n if (cached)\n return cached;\n cached = await webCryptoKey(false);\n return cached;\n}\n/** Forget the guest key on this device (a fresh signInAnonymously mints a new one). */\nexport async function clearGuestKey() {\n cached = null;\n try {\n getPlatform().storage.removeItem(LEGACY_STORED_SECRET_KEY);\n }\n catch (_a) { }\n try {\n if (typeof globalThis.indexedDB !== 'undefined') {\n const db = await idb();\n await new Promise((res) => {\n const r = db.transaction(IDB_STORE, 'readwrite').objectStore(IDB_STORE).delete(IDB_KEY);\n r.onsuccess = () => res();\n r.onerror = () => res();\n });\n }\n }\n catch (_b) { }\n}\n","import { getActiveSessionManager as SessionManager, createSessionWithSignature, genAuthNonce, genSolanaMessage, } from '@bounded-sh/core';\nimport { getPlatform } from '../../platform';\nimport { setCurrentUser, setAuthLoading } from '../../global';\nimport { getGuestKey, getExistingGuestKey, clearGuestKey } from './guest-keystore';\nconst GUEST_TX_UNSUPPORTED = 'Guest (anonymous) auth is offchain-only — it cannot sign or submit Solana transactions. ' +\n 'Use a wallet provider for onchain actions.';\nexport class GuestAuthProvider {\n async loginInternal(commitGlobalState, manageLoading) {\n if (manageLoading)\n setAuthLoading(true);\n try {\n const key = await getGuestKey();\n // Reuse a still-valid session for this exact guest.\n const existing = await SessionManager().getSession();\n if (existing && existing.address === key.address) {\n if (!this.tokenIsGuest(SessionManager().getIdToken(), key.address)) {\n throw new Error('The active session for this device key is not anonymous. Sign out explicitly before starting a guest session.');\n }\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n // Mint a fresh session: nonce -> canonical message -> local signature.\n const nonce = await genAuthNonce();\n const message = await genSolanaMessage(key.address, nonce);\n const signature = await key.sign(message); // base64 detached ed25519\n // Pass the discriminator explicitly. During a transactional switch the\n // shared core config intentionally remains on the previous provider until\n // this session is safely minted and persisted.\n const result = await createSessionWithSignature(key.address, message, signature, 'guest');\n if (!this.tokenIsGuest(result.idToken, key.address)) {\n throw new Error('Guest session issuer returned a non-anonymous or identity-mismatched token.');\n }\n await SessionManager().storeSession(key.address, result.accessToken, result.idToken, result.refreshToken);\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n finally {\n if (manageLoading)\n setAuthLoading(false);\n }\n }\n async login() {\n return this.loginInternal(true, true);\n }\n /** @internal Stage a guest session without exposing mixed provider/user state. */\n async loginForProviderSwitch() {\n return this.loginInternal(false, false);\n }\n tokenIsGuest(idToken, expectedAddress) {\n var _a;\n try {\n if (!idToken)\n return false;\n let b64 = (_a = idToken.split('.')[1]) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '+').replace(/_/g, '/');\n if (!b64)\n return false;\n const pad = b64.length % 4;\n if (pad === 2)\n b64 += '==';\n else if (pad === 3)\n b64 += '=';\n const claims = JSON.parse(getPlatform().atob(b64));\n if ((claims === null || claims === void 0 ? void 0 : claims.is_anonymous) !== true)\n return false;\n if (expectedAddress && (claims === null || claims === void 0 ? void 0 : claims['custom:walletAddress']) !== expectedAddress)\n return false;\n return true;\n }\n catch (_b) {\n return false;\n }\n }\n async restoreSessionInternal(commitGlobalState) {\n const manager = SessionManager();\n const session = await manager.getSession();\n if (!session)\n return null;\n // The marker/provider choice is not authority. A guest provider may only\n // continue with an issuer-stamped guest bearer whose persisted device key\n // still controls the exact same address. Anything else is an identity split\n // and must lose bearer authority immediately.\n if (!this.tokenIsGuest(manager.getIdToken(), session.address)) {\n await manager.clearSession();\n return null;\n }\n let key;\n try {\n key = await getExistingGuestKey();\n }\n catch (_a) {\n await manager.clearSession();\n return null;\n }\n if (!key || session.address !== key.address) {\n await manager.clearSession();\n return null;\n }\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n async restoreSession() {\n return this.restoreSessionInternal(true);\n }\n /** @internal Reconcile an applied-yet-error guest mint before committing a switch. */\n async restoreSessionForProviderSwitch() {\n return this.restoreSessionInternal(false);\n }\n async logout() {\n // Clears the SESSION but keeps the device key, so logging back in returns the\n // SAME guest identity (and its data). Use forgetGuest() to wipe the key too.\n await SessionManager().clearSession();\n setCurrentUser(null);\n }\n /** Wipe the device key — the next login() is a brand-new guest identity. */\n async forgetGuest() {\n await SessionManager().clearSession();\n await clearGuestKey();\n setCurrentUser(null);\n }\n async signMessage(message) {\n const key = await getGuestKey();\n return key.sign(message);\n }\n // --- offchain guest: no Solana transaction surface -------------------------\n async runTransaction(_evm, _sol, _options) {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async signTransaction(_t) {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async signAndSubmitTransaction() {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async getNativeMethods() {\n return {};\n }\n}\n"],"names":["bs58","getPlatform","setAuthLoading","SessionManager","setCurrentUser","genAuthNonce","genSolanaMessage","createSessionWithSignature"],"mappings":"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"}
1
+ {"version":3,"file":"guest-auth-provider-Di0TRg-z.js","sources":["../.rollup-tmp/auth/providers/guest-keystore.js","../.rollup-tmp/auth/providers/guest-auth-provider.js"],"sourcesContent":["// guest-keystore.ts — durable per-device keypair for anonymous (\"guest\") auth.\n//\n// A guest is an ed25519 keypair generated on the device. Its public key is the\n// Bounded account address; it signs the auth challenge exactly like a wallet.\n//\n// Guest auth has one backend: WebCrypto Ed25519 + IndexedDB. The key is\n// NON-EXTRACTABLE: an XSS can ask it to sign but can never read the private\n// bytes. If WebCrypto or IndexedDB is unavailable, guest auth fails closed\n// instead of silently creating an extractable/stored-secret credential.\n//\n// The public output is a base58 address + a base64\n// detached signature, which is the format the session endpoint already accepts.\nimport bs58 from 'bs58';\nimport { getPlatform } from '../../platform';\nconst LEGACY_STORED_SECRET_KEY = 'bounded_guest_key_v1';\nconst IDB_NAME = 'bounded-guest';\nconst IDB_STORE = 'keys';\nconst IDB_KEY = 'ed25519';\nconst GUEST_KEY_REQUIREMENT = 'Guest auth requires non-extractable WebCrypto Ed25519 keys persisted in IndexedDB; ' +\n 'stored-secret guest credentials are disabled.';\nfunction toBase64(bytes) {\n let bin = '';\n for (let i = 0; i < bytes.length; i++)\n bin += String.fromCharCode(bytes[i]);\n // btoa exists in browsers + RN (Hermes) ; Buffer is the Node/SSR fallback.\n return typeof btoa !== 'undefined' ? btoa(bin) : Buffer.from(bytes).toString('base64');\n}\n// ----- WebCrypto (non-extractable) backend -----------------------------------\nfunction subtle() {\n const c = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto;\n return c && c.subtle ? c.subtle : null;\n}\nfunction idb() {\n return new Promise((resolve, reject) => {\n const req = globalThis.indexedDB.open(IDB_NAME, 1);\n req.onupgradeneeded = () => req.result.createObjectStore(IDB_STORE);\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\nfunction idbGet(db, key) {\n return new Promise((resolve, reject) => {\n const r = db.transaction(IDB_STORE, 'readonly').objectStore(IDB_STORE).get(key);\n r.onsuccess = () => resolve(r.result);\n r.onerror = () => reject(r.error);\n });\n}\nfunction idbPut(db, key, val) {\n return new Promise((resolve, reject) => {\n const r = db.transaction(IDB_STORE, 'readwrite').objectStore(IDB_STORE).put(val, key);\n r.onsuccess = () => resolve();\n r.onerror = () => reject(r.error);\n });\n}\nfunction guestKeyUnavailable(cause) {\n const detail = cause instanceof Error && cause.message ? ` Cause: ${cause.message}` : '';\n return new Error(`${GUEST_KEY_REQUIREMENT}${detail}`);\n}\nasync function webCryptoKey(createIfMissing) {\n const s = subtle();\n if (!s)\n throw guestKeyUnavailable(new Error('WebCrypto subtle crypto is unavailable.'));\n if (typeof globalThis.indexedDB === 'undefined') {\n throw guestKeyUnavailable(new Error('IndexedDB is unavailable.'));\n }\n try {\n const db = await idb();\n let pair = (await idbGet(db, IDB_KEY));\n if (!pair) {\n if (!createIfMissing)\n return null;\n // Probe Ed25519 support by generating (throws on unsupported engines).\n pair = (await s.generateKey({ name: 'Ed25519' }, /* extractable */ false, [\n 'sign',\n 'verify',\n ]));\n await idbPut(db, IDB_KEY, pair); // CryptoKey is structured-cloneable; bytes never exposed\n }\n const raw = new Uint8Array(await s.exportKey('raw', pair.publicKey)); // public is exportable\n const address = bs58.encode(raw);\n return {\n address,\n nonExtractable: true,\n async sign(message) {\n const data = new TextEncoder().encode(message);\n const sig = new Uint8Array(await s.sign({ name: 'Ed25519' }, pair.privateKey, data));\n return toBase64(sig);\n },\n };\n }\n catch (error) {\n throw guestKeyUnavailable(error);\n }\n}\nlet cached = null;\n/** Get (or create) this device's durable guest key. */\nexport async function getGuestKey() {\n if (cached)\n return cached;\n cached = await webCryptoKey(true);\n if (!cached)\n throw guestKeyUnavailable(new Error('Guest key creation returned no key.'));\n return cached;\n}\n/** Read the existing durable guest key without ever minting a replacement. */\nexport async function getExistingGuestKey() {\n if (cached)\n return cached;\n cached = await webCryptoKey(false);\n return cached;\n}\n/** Forget the guest key on this device (a fresh signInAnonymously mints a new one). */\nexport async function clearGuestKey() {\n cached = null;\n try {\n getPlatform().storage.removeItem(LEGACY_STORED_SECRET_KEY);\n }\n catch (_a) { }\n try {\n if (typeof globalThis.indexedDB !== 'undefined') {\n const db = await idb();\n await new Promise((res) => {\n const r = db.transaction(IDB_STORE, 'readwrite').objectStore(IDB_STORE).delete(IDB_KEY);\n r.onsuccess = () => res();\n r.onerror = () => res();\n });\n }\n }\n catch (_b) { }\n}\n","import { getActiveSessionManager as SessionManager, createSessionWithSignature, genAuthNonce, genSolanaMessage, } from '@bounded-sh/core';\nimport { getPlatform } from '../../platform';\nimport { setCurrentUser, setAuthLoading } from '../../global';\nimport { getGuestKey, getExistingGuestKey, clearGuestKey } from './guest-keystore';\nconst GUEST_TX_UNSUPPORTED = 'Guest (anonymous) auth is offchain-only — it cannot sign or submit Solana transactions. ' +\n 'Use a wallet provider for onchain actions.';\nexport class GuestAuthProvider {\n async loginInternal(commitGlobalState, manageLoading) {\n if (manageLoading)\n setAuthLoading(true);\n try {\n const key = await getGuestKey();\n // Reuse a still-valid session for this exact guest.\n const existing = await SessionManager().getSession();\n if (existing && existing.address === key.address) {\n if (!this.tokenIsGuest(SessionManager().getIdToken(), key.address)) {\n throw new Error('The active session for this device key is not anonymous. Sign out explicitly before starting a guest session.');\n }\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n // Mint a fresh session: nonce -> canonical message -> local signature.\n const nonce = await genAuthNonce();\n const message = await genSolanaMessage(key.address, nonce);\n const signature = await key.sign(message); // base64 detached ed25519\n // Pass the discriminator explicitly. During a transactional switch the\n // shared core config intentionally remains on the previous provider until\n // this session is safely minted and persisted.\n const result = await createSessionWithSignature(key.address, message, signature, 'guest');\n if (!this.tokenIsGuest(result.idToken, key.address)) {\n throw new Error('Guest session issuer returned a non-anonymous or identity-mismatched token.');\n }\n await SessionManager().storeSession(key.address, result.accessToken, result.idToken, result.refreshToken);\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n finally {\n if (manageLoading)\n setAuthLoading(false);\n }\n }\n async login() {\n return this.loginInternal(true, true);\n }\n /** @internal Stage a guest session without exposing mixed provider/user state. */\n async loginForProviderSwitch() {\n return this.loginInternal(false, false);\n }\n tokenIsGuest(idToken, expectedAddress) {\n var _a;\n try {\n if (!idToken)\n return false;\n let b64 = (_a = idToken.split('.')[1]) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '+').replace(/_/g, '/');\n if (!b64)\n return false;\n const pad = b64.length % 4;\n if (pad === 2)\n b64 += '==';\n else if (pad === 3)\n b64 += '=';\n const claims = JSON.parse(getPlatform().atob(b64));\n if ((claims === null || claims === void 0 ? void 0 : claims.is_anonymous) !== true)\n return false;\n if (expectedAddress && (claims === null || claims === void 0 ? void 0 : claims['custom:walletAddress']) !== expectedAddress)\n return false;\n return true;\n }\n catch (_b) {\n return false;\n }\n }\n async restoreSessionInternal(commitGlobalState) {\n const manager = SessionManager();\n const session = await manager.getSession();\n if (!session)\n return null;\n // The marker/provider choice is not authority. A guest provider may only\n // continue with an issuer-stamped guest bearer whose persisted device key\n // still controls the exact same address. Anything else is an identity split\n // and must lose bearer authority immediately.\n if (!this.tokenIsGuest(manager.getIdToken(), session.address)) {\n await manager.clearSession();\n return null;\n }\n let key;\n try {\n key = await getExistingGuestKey();\n }\n catch (_a) {\n await manager.clearSession();\n return null;\n }\n if (!key || session.address !== key.address) {\n await manager.clearSession();\n return null;\n }\n const user = { address: key.address, isAnonymous: true, provider: this };\n if (commitGlobalState)\n setCurrentUser(user);\n return user;\n }\n async restoreSession() {\n return this.restoreSessionInternal(true);\n }\n /** @internal Reconcile an applied-yet-error guest mint before committing a switch. */\n async restoreSessionForProviderSwitch() {\n return this.restoreSessionInternal(false);\n }\n async logout() {\n // Clears the SESSION but keeps the device key, so logging back in returns the\n // SAME guest identity (and its data). Use forgetGuest() to wipe the key too.\n await SessionManager().clearSession();\n setCurrentUser(null);\n }\n /** Wipe the device key — the next login() is a brand-new guest identity. */\n async forgetGuest() {\n await SessionManager().clearSession();\n await clearGuestKey();\n setCurrentUser(null);\n }\n async signMessage(message) {\n const key = await getGuestKey();\n return key.sign(message);\n }\n // --- offchain guest: no Solana transaction surface -------------------------\n async runTransaction(_evm, _sol, _options) {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async signTransaction(_t) {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async signAndSubmitTransaction() {\n throw new Error(GUEST_TX_UNSUPPORTED);\n }\n async getNativeMethods() {\n return {};\n }\n}\n"],"names":["bs58","getPlatform","setAuthLoading","SessionManager","setCurrentUser","genAuthNonce","genSolanaMessage","createSessionWithSignature"],"mappings":"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"}
@@ -3707,6 +3707,7 @@ const OIDC_NO_WALLET = 'This login has no embedded wallet. Enable `"auth": { "wa
3707
3707
  'then sign from a user gesture.';
3708
3708
  const PKCE_STORE_KEY = 'bounded.oidc.pkce';
3709
3709
  const STORED_AUTH_METHOD_KEY$1 = 'bounded_last_auth_method';
3710
+ const ISSUER_SESSION_KIND_KEY$1 = 'bounded_issuer_session_kind';
3710
3711
  // Active session store (Web on web, RN on React Native) — selected by config,
3711
3712
  // not by `typeof window` (truthy on RN). OIDC redirect/popup is web-only, but the
3712
3713
  // session it mints is read back through this same selector everywhere.
@@ -4195,6 +4196,13 @@ async function establishInlineSession(data) {
4195
4196
  getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$1, 'email');
4196
4197
  }
4197
4198
  catch ( /* storage unavailable */_a) { /* storage unavailable */ }
4199
+ // Turnkey-native OTP mints an app session directly. It does not establish a
4200
+ // Better Auth browser cookie on the issuer, so logout must not navigate
4201
+ // through the issuer's cookie-clearing /logout endpoint.
4202
+ try {
4203
+ getPlatform().storage.setItem(ISSUER_SESSION_KIND_KEY$1, 'inline');
4204
+ }
4205
+ catch ( /* storage unavailable */_b) { /* storage unavailable */ }
4198
4206
  setCurrentUser(user);
4199
4207
  setAuthProviderInstance(oidcProviderSingleton);
4200
4208
  return user;
@@ -4241,6 +4249,13 @@ async function exchangeCode(code, verifier, redirectUri) {
4241
4249
  getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$1, 'email');
4242
4250
  }
4243
4251
  catch ( /* storage unavailable */_b) { /* storage unavailable */ }
4252
+ // OIDC login does establish the issuer's Better Auth browser cookie. Record
4253
+ // that fact separately from the provider name so logout clears the cookie
4254
+ // and returns through the registered app origin.
4255
+ try {
4256
+ getPlatform().storage.setItem(ISSUER_SESSION_KIND_KEY$1, 'hosted');
4257
+ }
4258
+ catch ( /* storage unavailable */_c) { /* storage unavailable */ }
4244
4259
  setCurrentUser(user);
4245
4260
  setAuthProviderInstance(oidcProviderSingleton);
4246
4261
  return user;
@@ -4257,6 +4272,7 @@ const objectIdentityKeys = new WeakMap();
4257
4272
  let nextObjectIdentityKey = 1;
4258
4273
  // --- localStorage helpers: track which auth method created the active session ---
4259
4274
  const STORED_AUTH_METHOD_KEY = 'bounded_last_auth_method';
4275
+ const ISSUER_SESSION_KIND_KEY = 'bounded_issuer_session_kind';
4260
4276
  function getStoredAuthMethod() {
4261
4277
  try {
4262
4278
  return getPlatform().storage.getItem(STORED_AUTH_METHOD_KEY);
@@ -4273,11 +4289,25 @@ function setStoredAuthMethod(method) {
4273
4289
  else {
4274
4290
  getPlatform().storage.removeItem(STORED_AUTH_METHOD_KEY);
4275
4291
  }
4292
+ // Non-email providers cannot own a Better Auth browser session. Clear
4293
+ // any prior hosted/inline classification when the active provider is
4294
+ // replaced or the session is removed.
4295
+ if (method !== 'email') {
4296
+ getPlatform().storage.removeItem(ISSUER_SESSION_KIND_KEY);
4297
+ }
4276
4298
  }
4277
4299
  catch (_a) {
4278
4300
  // storage might not be available
4279
4301
  }
4280
4302
  }
4303
+ function getIssuerSessionKind() {
4304
+ try {
4305
+ return getPlatform().storage.getItem(ISSUER_SESSION_KIND_KEY);
4306
+ }
4307
+ catch (_a) {
4308
+ return null;
4309
+ }
4310
+ }
4281
4311
  function getStoredIdToken() {
4282
4312
  try {
4283
4313
  return core.getActiveSessionManager().getIdToken();
@@ -4536,7 +4566,7 @@ async function getAuthProvider(config) {
4536
4566
  // manager as legacy email sessions. Human login should be started
4537
4567
  // with loginWithRedirect(); this provider is kept as the restore and
4538
4568
  // logout surface for those sessions.
4539
- currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-N-dfsNnE.js'); })).EmailAuthProvider();
4569
+ currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-9BwSziWj.js'); })).EmailAuthProvider();
4540
4570
  break;
4541
4571
  case "wallet":
4542
4572
  case "phantom": {
@@ -4555,7 +4585,7 @@ async function getAuthProvider(config) {
4555
4585
  if (!isWalletLoginEnabled(config)) {
4556
4586
  throw walletLoginNotEnabledError(authMethod);
4557
4587
  }
4558
- const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-CVeZgfEt.js'); });
4588
+ const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-oCRGuls5.js'); });
4559
4589
  currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
4560
4590
  break;
4561
4591
  }
@@ -4568,7 +4598,7 @@ async function getAuthProvider(config) {
4568
4598
  // Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
4569
4599
  // to point at a specific wallet or set chainId/domain.
4570
4600
  const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
4571
- const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-CItxws1D.js'); });
4601
+ const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-DgWUaVtt.js'); });
4572
4602
  currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
4573
4603
  break;
4574
4604
  }
@@ -4596,7 +4626,7 @@ async function getAuthProvider(config) {
4596
4626
  break;
4597
4627
  case "guest":
4598
4628
  // Anonymous auth: a device-local ed25519 keypair signs the challenge.
4599
- currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-BFodq9Rc.js'); })).GuestAuthProvider();
4629
+ currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-Di0TRg-z.js'); })).GuestAuthProvider();
4600
4630
  break;
4601
4631
  }
4602
4632
  if (!currentAuthProvider) {
@@ -4652,7 +4682,7 @@ async function signInAnonymously() {
4652
4682
  // Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
4653
4683
  // the main bundle for data-only apps. Specifier is a static string literal
4654
4684
  // so bundle-splitting can see it.
4655
- const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-BFodq9Rc.js'); })).GuestAuthProvider();
4685
+ const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-Di0TRg-z.js'); })).GuestAuthProvider();
4656
4686
  setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
4657
4687
  const commit = (user) => {
4658
4688
  // No await/interleaving inside this block: provider/method/config/marker
@@ -4803,7 +4833,7 @@ async function loginWithWallet(options) {
4803
4833
  ? Object.assign(Object.assign({}, base), { getProvider: options.getProvider }) : base;
4804
4834
  const rpcUrl = normalizeSolanaRpcUrl(cfg.rpcUrl);
4805
4835
  const network = getConfiguredSolanaNetwork(cfg);
4806
- const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-CVeZgfEt.js'); });
4836
+ const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-oCRGuls5.js'); });
4807
4837
  let provider = new InjectedWalletProvider(injectedConfig, rpcUrl, network);
4808
4838
  if (coreConfig.chain === 'offchain')
4809
4839
  provider = new OffchainAuthProvider(provider);
@@ -4875,7 +4905,7 @@ function getCurrentAuthMethod() {
4875
4905
  // allowlist here: on a trusted origin we end the issuer session with a
4876
4906
  // top-level bounce; anywhere else (custom domains, http dev) we keep the
4877
4907
  // local-only logout instead of stranding the user on the issuer origin.
4878
- function issuerLogoutBounceUrl(issuerBase) {
4908
+ function issuerLogoutBounceUrl(issuerBase, idTokenHint) {
4879
4909
  if (typeof window === 'undefined' || typeof document === 'undefined')
4880
4910
  return null; // RN/Node: no shared cookie jar to clear this way
4881
4911
  try {
@@ -4898,12 +4928,27 @@ function issuerLogoutBounceUrl(issuerBase) {
4898
4928
  if (!trusted)
4899
4929
  return null;
4900
4930
  const base = issuerBase.replace(/\/$/, '');
4901
- return `${base}/logout?redirect_uri=${encodeURIComponent(here.href)}`;
4931
+ // #228: send the id_token_hint so the issuer can bind the post-logout redirect to this
4932
+ // session + app + registered origin. Without it the issuer safely falls back to its own
4933
+ // origin (it no longer trusts a bare suffix match), so the return-to-app bounce is a no-op.
4934
+ const hint = idTokenHint ? `&id_token_hint=${encodeURIComponent(idTokenHint)}` : '';
4935
+ return `${base}/logout?redirect_uri=${encodeURIComponent(here.href)}${hint}`;
4902
4936
  }
4903
4937
  catch (_b) {
4904
4938
  return null;
4905
4939
  }
4906
4940
  }
4941
+ // #228 helper, deliberately OUTSIDE logout(): the logout body is source-guarded
4942
+ // against any `catch` so a revokeSession failure can never be swallowed, and a
4943
+ // missing id token is the one benign absence worth tolerating here.
4944
+ function idTokenHintOrNull(sm) {
4945
+ try {
4946
+ return sm.getIdToken();
4947
+ }
4948
+ catch (_a) {
4949
+ return null; /* no id token to hint with */
4950
+ }
4951
+ }
4907
4952
  async function logout$1(options) {
4908
4953
  // Re-initialize the provider if it was cleared by a prior logout — the exact mirror
4909
4954
  // of login()'s self-heal above. A hosted popup/redirect login (loginWithPopup /
@@ -4928,17 +4973,20 @@ async function logout$1(options) {
4928
4973
  const sm = core.getActiveSessionManager();
4929
4974
  const refreshToken = sm.getRefreshToken();
4930
4975
  const sessionIssuer = sm.getIssuer();
4976
+ // #228: capture the id token NOW, before currentAuthProvider.logout() clears the session, so we
4977
+ // can hand it to the issuer /logout as an id_token_hint (which binds the post-logout redirect).
4978
+ const idTokenHint = idTokenHintOrNull(sm);
4931
4979
  if (refreshToken)
4932
4980
  await core.revokeSession(refreshToken, sessionIssuer !== null && sessionIssuer !== void 0 ? sessionIssuer : undefined);
4933
- // Hosted sessions ('email' covers the whole hosted surface: email OTP +
4934
- // social + the OIDC redirect/popup flows) are the ones with an issuer
4935
- // cookie; wallet and guest sessions have nothing hosted to end.
4936
- // Check the STORED marker as well as the in-memory method: the hosted
4937
- // OIDC flows (loginWithPopup / completeLoginFromRedirect) write the
4938
- // 'email' marker via exchangeCode() but never touch currentAuthMethod,
4939
- // which stays 'guest'/explicit even after a hosted upgrade. Worst case of
4940
- // a false positive is a harmless idempotent issuer bounce.
4941
- const wasHosted = currentAuthMethod === 'email' || getStoredAuthMethod() === 'email';
4981
+ // Only OIDC-hosted sessions own an issuer browser cookie. Turnkey-native
4982
+ // email OTP is also an email auth method, but it mints the app session
4983
+ // inline and has no issuer cookie to clear. Use the explicit session-kind
4984
+ // marker when present. The auth-method fallback preserves correct logout
4985
+ // behavior for hosted sessions created by older SDK versions.
4986
+ const issuerSessionKind = getIssuerSessionKind();
4987
+ const wasHosted = issuerSessionKind === 'hosted'
4988
+ || (issuerSessionKind === null
4989
+ && (currentAuthMethod === 'email' || getStoredAuthMethod() === 'email'));
4942
4990
  await currentAuthProvider.logout();
4943
4991
  setStoredAuthMethod(null);
4944
4992
  currentAuthProvider = null;
@@ -4948,7 +4996,7 @@ async function logout$1(options) {
4948
4996
  const issuerBase = sessionIssuer
4949
4997
  || (await core.getConfig()).humanAuthApiUrl
4950
4998
  || 'https://auth.bounded.sh';
4951
- const bounce = issuerLogoutBounceUrl(issuerBase);
4999
+ const bounce = issuerLogoutBounceUrl(issuerBase, idTokenHint);
4952
5000
  // Local state is already cleared, so even if the navigation is stopped
4953
5001
  // (tab close, extension) the app-side logout has fully happened.
4954
5002
  if (bounce)
@@ -7384,30 +7432,117 @@ async function signSolanaMessageViaTurnkey(message) {
7384
7432
  // session is bound server-side to the caller's verified Bounded JWT, and the
7385
7433
  // destination defaults to that user's embedded wallet.
7386
7434
  //
7435
+ // Amount semantics:
7436
+ // amountUsd - exact fiat in; the fee/output breakdown comes back as `quote`.
7437
+ // minAmountOut - a FLOOR on crypto received. The platform quotes Coinbase's
7438
+ // worst-fee payment method (card) and pads by `slippagePad` (default 1%),
7439
+ // so cheaper methods overshoot the floor rather than undershooting it. The
7440
+ // floor holds unless the market moves more than the pad while the user sits
7441
+ // on the checkout screen - which is why completion is VERIFIED: after the
7442
+ // popup closes we poll the platform's status leg and resolve with the
7443
+ // actual filled amount when Coinbase reports it.
7444
+ //
7387
7445
  // Works on Bounded-served origins (<app>.bounded.page / custom domains). On a
7388
7446
  // local dev origin the session endpoint does not exist; we fail with a clear
7389
7447
  // error rather than guessing a host.
7390
7448
  function hasDOM() {
7391
7449
  return typeof window !== 'undefined' && typeof document !== 'undefined';
7392
7450
  }
7451
+ async function authedFetch(path, init) {
7452
+ const idToken = await getIdToken();
7453
+ if (!idToken)
7454
+ throw new Error('onramp: no active session - call login() first');
7455
+ return fetch(`${window.location.origin}${path}`, Object.assign(Object.assign({}, init), { headers: Object.assign(Object.assign({}, init === null || init === void 0 ? void 0 : init.headers), { Authorization: `Bearer ${idToken}` }) }));
7456
+ }
7457
+ async function readError(res) {
7458
+ var _a;
7459
+ try {
7460
+ return (_a = (await res.json()).error) !== null && _a !== void 0 ? _a : '';
7461
+ }
7462
+ catch (_b) {
7463
+ return '';
7464
+ }
7465
+ }
7466
+ function sessionBody(options, extra) {
7467
+ return JSON.stringify(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (options.asset ? { asset: options.asset } : {})), (options.address ? { address: options.address } : {})), (options.amountUsd !== undefined ? { amountUsd: options.amountUsd } : {})), (options.minAmountOut !== undefined ? { minAmountOut: options.minAmountOut } : {})), (options.slippagePad !== undefined ? { slippagePad: options.slippagePad } : {})), extra));
7468
+ }
7469
+ function resolveAddress(options) {
7470
+ var _a, _b;
7471
+ const user = getCurrentUser();
7472
+ const address = (_b = (_a = options.address) !== null && _a !== void 0 ? _a : user === null || user === void 0 ? void 0 : user.address) !== null && _b !== void 0 ? _b : undefined;
7473
+ if (!address) {
7474
+ throw new Error(user
7475
+ ? 'onramp: the signed-in account has no wallet address - pass { address } explicitly'
7476
+ : 'onramp: no signed-in user - call login() first or pass { address }');
7477
+ }
7478
+ return address;
7479
+ }
7393
7480
  /**
7394
- * Open Coinbase Onramp for the signed-in user. Resolves when the popup closes.
7481
+ * Preview a quote (fees + exact/floor output) WITHOUT opening any window or
7482
+ * consuming a session. Show this to the user, then call onramp() to check out.
7483
+ */
7484
+ async function onrampQuote(options = {}) {
7485
+ if (!hasDOM())
7486
+ throw new Error('onrampQuote is web-only');
7487
+ resolveAddress(options);
7488
+ const res = await authedFetch('/__bounded/onramp/session', {
7489
+ method: 'POST',
7490
+ headers: { 'content-type': 'application/json' },
7491
+ body: sessionBody(options, { quoteOnly: true }),
7492
+ });
7493
+ if (!res.ok)
7494
+ throw new Error(`onrampQuote: failed (${res.status}${await readError(res).then((e) => (e ? `: ${e}` : ''))})`);
7495
+ return (await res.json());
7496
+ }
7497
+ /** The signed-in user's recent onramp transactions (newest first). */
7498
+ async function onrampStatus(sinceMs) {
7499
+ if (!hasDOM())
7500
+ throw new Error('onrampStatus is web-only');
7501
+ const res = await authedFetch(`/__bounded/onramp/status${sinceMs ? `?since=${Math.floor(sinceMs)}` : ''}`);
7502
+ if (!res.ok)
7503
+ throw new Error(`onrampStatus: failed (${res.status})`);
7504
+ return (await res.json()).transactions;
7505
+ }
7506
+ function isSuccess(t) {
7507
+ return /SUCCESS|COMPLETED/i.test(t.status);
7508
+ }
7509
+ function isPending(t) {
7510
+ return /PROGRESS|PENDING|CREATED/i.test(t.status);
7511
+ }
7512
+ async function verifyCompletion(openedAt, asset, timeoutMs) {
7513
+ const deadline = Date.now() + timeoutMs;
7514
+ // 60s of clock-skew slack on `since`: Coinbase stamps server-side.
7515
+ const since = openedAt - 60000;
7516
+ for (;;) {
7517
+ let sawPending = false;
7518
+ try {
7519
+ const txs = await onrampStatus(since);
7520
+ const done = txs.find((t) => isSuccess(t) && (t.asset === null || t.asset === asset));
7521
+ if (done)
7522
+ return done;
7523
+ sawPending = txs.some(isPending);
7524
+ }
7525
+ catch ( /* transient - keep polling until the deadline */_a) { /* transient - keep polling until the deadline */ }
7526
+ // No completed fill and nothing in flight: one grace poll cycle still
7527
+ // runs (Coinbase's record can lag the redirect), but don't burn the
7528
+ // full window when the user plainly abandoned checkout.
7529
+ if (Date.now() >= deadline)
7530
+ return null;
7531
+ if (!sawPending && Date.now() >= openedAt + 12000 && Date.now() - openedAt > timeoutMs / 2)
7532
+ return null;
7533
+ await new Promise((r) => setTimeout(r, 3000));
7534
+ }
7535
+ }
7536
+ /**
7537
+ * Open Coinbase Onramp for the signed-in user. Resolves after the window
7538
+ * closes, with completion VERIFIED against Coinbase when possible.
7395
7539
  * Call from a click handler - popup blockers require user activation.
7396
7540
  */
7397
7541
  async function onramp(options = {}) {
7398
- var _a, _b, _c;
7542
+ var _a;
7399
7543
  if (!hasDOM())
7400
7544
  throw new Error('onramp() is web-only');
7401
- const user = getCurrentUser();
7402
- const address = (_b = (_a = options.address) !== null && _a !== void 0 ? _a : user === null || user === void 0 ? void 0 : user.address) !== null && _b !== void 0 ? _b : undefined;
7403
- if (!address) {
7404
- throw new Error(user
7405
- ? 'onramp(): the signed-in account has no wallet address - pass { address } explicitly'
7406
- : 'onramp(): no signed-in user - call login() first or pass { address }');
7407
- }
7408
- const idToken = await getIdToken();
7409
- if (!idToken)
7410
- throw new Error('onramp(): no active session - call login() first');
7545
+ resolveAddress(options);
7411
7546
  // Open the window synchronously so the click's user-activation window is not
7412
7547
  // consumed by the fetch below (same hard-won pattern as loginWithPopup).
7413
7548
  let popup = null;
@@ -7420,21 +7555,17 @@ async function onramp(options = {}) {
7420
7555
  }
7421
7556
  let session;
7422
7557
  try {
7423
- const res = await fetch(`${window.location.origin}/__bounded/onramp/session`, {
7558
+ const res = await authedFetch('/__bounded/onramp/session', {
7424
7559
  method: 'POST',
7425
- headers: { Authorization: `Bearer ${idToken}`, 'content-type': 'application/json' },
7426
- body: JSON.stringify(Object.assign(Object.assign(Object.assign({}, (options.asset ? { asset: options.asset } : {})), (options.address ? { address: options.address } : {})), (options.amountUsd !== undefined ? { amountUsd: options.amountUsd } : {}))),
7560
+ headers: { 'content-type': 'application/json' },
7561
+ body: sessionBody(options),
7427
7562
  });
7428
7563
  if (!res.ok) {
7429
- let detail = '';
7430
- try {
7431
- detail = (_c = (await res.json()).error) !== null && _c !== void 0 ? _c : '';
7432
- }
7433
- catch ( /* keep status only */_d) { /* keep status only */ }
7564
+ const detail = await readError(res);
7434
7565
  if (res.status === 404) {
7435
- throw new Error('onramp(): session endpoint not found - onramp works on Bounded-served origins (your deployed app URL), not local dev servers');
7566
+ throw new Error('onramp: session endpoint not found - onramp works on Bounded-served origins (your deployed app URL), not local dev servers');
7436
7567
  }
7437
- throw new Error(`onramp(): session mint failed (${res.status}${detail ? `: ${detail}` : ''})`);
7568
+ throw new Error(`onramp: session mint failed (${res.status}${detail ? `: ${detail}` : ''})`);
7438
7569
  }
7439
7570
  session = (await res.json());
7440
7571
  }
@@ -7442,40 +7573,47 @@ async function onramp(options = {}) {
7442
7573
  try {
7443
7574
  popup === null || popup === void 0 ? void 0 : popup.close();
7444
7575
  }
7445
- catch ( /* ignore */_e) { /* ignore */ }
7576
+ catch ( /* ignore */_b) { /* ignore */ }
7446
7577
  throw error;
7447
7578
  }
7579
+ const openedAt = Date.now();
7580
+ const base = Object.assign({ address: session.address, asset: session.asset }, (session.quote ? { quote: session.quote } : {}));
7448
7581
  if (popup) {
7449
7582
  try {
7450
7583
  popup.location.replace(session.url);
7451
7584
  }
7452
- catch (_f) {
7585
+ catch (_c) {
7453
7586
  try {
7454
7587
  popup.location.href = session.url;
7455
7588
  }
7456
- catch (_g) {
7589
+ catch (_d) {
7457
7590
  try {
7458
7591
  popup.close();
7459
7592
  }
7460
- catch ( /* ignore */_h) { /* ignore */ }
7461
- throw new Error('onramp(): popup failed to navigate - retry with { newTab: true }');
7593
+ catch ( /* ignore */_e) { /* ignore */ }
7594
+ throw new Error('onramp: popup failed to navigate - retry with { newTab: true }');
7462
7595
  }
7463
7596
  }
7464
- return await new Promise((resolve) => {
7597
+ await new Promise((resolve) => {
7465
7598
  const timer = setInterval(() => {
7466
7599
  if (popup.closed) {
7467
7600
  clearInterval(timer);
7468
- resolve({ status: 'closed', address: session.address, asset: session.asset });
7601
+ resolve();
7469
7602
  }
7470
7603
  }, 500);
7471
7604
  });
7605
+ const fill = await verifyCompletion(openedAt, session.asset, (_a = options.completionTimeoutMs) !== null && _a !== void 0 ? _a : 24000);
7606
+ if (fill) {
7607
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, base), { status: 'completed' }), (fill.amountOut !== null ? { actualOut: fill.amountOut } : {})), (fill.txHash ? { txHash: fill.txHash } : {}));
7608
+ }
7609
+ return Object.assign(Object.assign({}, base), { status: 'closed' });
7472
7610
  }
7473
7611
  // New-tab path (popup was blocked or explicitly requested): cross-origin tab
7474
- // close is not observable, so resolve immediately.
7612
+ // close is not observable, so resolve immediately; verify via onrampStatus().
7475
7613
  const tab = window.open(session.url, '_blank');
7476
7614
  if (!tab)
7477
- throw new Error('onramp(): window.open was blocked - call onramp() from a click handler');
7478
- return { status: 'opened', address: session.address, asset: session.asset };
7615
+ throw new Error('onramp: window.open was blocked - call onramp() from a click handler');
7616
+ return Object.assign(Object.assign({}, base), { status: 'opened' });
7479
7617
  }
7480
7618
 
7481
7619
  /**
@@ -7989,6 +8127,8 @@ exports.normalizeSolanaRpcUrl = normalizeSolanaRpcUrl;
7989
8127
  exports.onAuthLoadingChanged = onAuthLoadingChanged;
7990
8128
  exports.onAuthStateChanged = onAuthStateChanged;
7991
8129
  exports.onramp = onramp;
8130
+ exports.onrampQuote = onrampQuote;
8131
+ exports.onrampStatus = onrampStatus;
7992
8132
  exports.openBoundedWidget = openBoundedWidget;
7993
8133
  exports.requestEip6963Providers = requestEip6963Providers;
7994
8134
  exports.resolveSolanaRpcUrl = resolveSolanaRpcUrl;
@@ -8001,4 +8141,4 @@ exports.startTurnkeyEmailLogin = startTurnkeyEmailLogin;
8001
8141
  exports.useAuth = useAuth;
8002
8142
  exports.useBuildRun = useBuildRun;
8003
8143
  exports.useQuery = useQuery;
8004
- //# sourceMappingURL=index-uu8hKP-p.js.map
8144
+ //# sourceMappingURL=index-C_L497w1.js.map