@bounded-sh/client 0.0.58 → 0.0.59
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.
- package/dist/auth/index.d.ts +1 -1
- package/dist/{email-auth-provider-BlJI-8w9.js → email-auth-provider-BSw9FRjg.js} +3 -3
- package/dist/email-auth-provider-BSw9FRjg.js.map +1 -0
- package/dist/{email-auth-provider-CX7foEhA.mjs → email-auth-provider-DhAMOILG.mjs} +3 -3
- package/dist/email-auth-provider-DhAMOILG.mjs.map +1 -0
- package/dist/{email-auth-provider-BHtR1H_E.js → email-auth-provider-N-dfsNnE.js} +3 -3
- package/dist/email-auth-provider-N-dfsNnE.js.map +1 -0
- package/dist/{email-auth-provider-CfNSS8Du.mjs → email-auth-provider-deB_ADc5.mjs} +3 -3
- package/dist/email-auth-provider-deB_ADc5.mjs.map +1 -0
- package/dist/{guest-auth-provider-DJmuReVa.mjs → guest-auth-provider-B78Ugfar.mjs} +7 -7
- package/dist/guest-auth-provider-B78Ugfar.mjs.map +1 -0
- package/dist/{guest-auth-provider-BPXDJoEQ.js → guest-auth-provider-BFodq9Rc.js} +7 -7
- package/dist/guest-auth-provider-BFodq9Rc.js.map +1 -0
- package/dist/{guest-auth-provider-BRjJV8Zq.js → guest-auth-provider-Czl48mOP.js} +7 -7
- package/dist/guest-auth-provider-Czl48mOP.js.map +1 -0
- package/dist/{guest-auth-provider-DxhZ5sWN.mjs → guest-auth-provider-D9wbogwi.mjs} +7 -7
- package/dist/guest-auth-provider-D9wbogwi.mjs.map +1 -0
- package/dist/{index-DWodlTFG.mjs → index-SHt4VZZV.mjs} +173 -35
- package/dist/index-SHt4VZZV.mjs.map +1 -0
- package/dist/{index-MKE9tHpl.js → index-uu8hKP-p.js} +172 -33
- package/dist/index-uu8hKP-p.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{index.native-CQiw9baS.mjs → index.native-D-8IAEy-.mjs} +162 -24
- package/dist/index.native-D-8IAEy-.mjs.map +1 -0
- package/dist/{index.native-hu3o3zXU.js → index.native-D48QQ0-q.js} +161 -22
- package/dist/index.native-D48QQ0-q.js.map +1 -0
- package/dist/index.native.d.ts +2 -0
- package/dist/index.native.js +2 -1
- package/dist/index.native.js.map +1 -1
- package/dist/index.native.mjs +1 -1
- package/dist/{injected-evm-wallet-provider-BOPzdm7E.js → injected-evm-wallet-provider-CItxws1D.js} +4 -4
- package/dist/injected-evm-wallet-provider-CItxws1D.js.map +1 -0
- package/dist/{injected-evm-wallet-provider-DCGnUedJ.mjs → injected-evm-wallet-provider-CJsLX16m.mjs} +4 -4
- package/dist/injected-evm-wallet-provider-CJsLX16m.mjs.map +1 -0
- package/dist/{injected-evm-wallet-provider-Xbt2CUPi.js → injected-evm-wallet-provider-HQMOL_mZ.js} +4 -4
- package/dist/injected-evm-wallet-provider-HQMOL_mZ.js.map +1 -0
- package/dist/{injected-evm-wallet-provider-CnJRLE8P.mjs → injected-evm-wallet-provider-UWvcy-LO.mjs} +4 -4
- package/dist/injected-evm-wallet-provider-UWvcy-LO.mjs.map +1 -0
- package/dist/{injected-wallet-provider-Dg3MieTq.mjs → injected-wallet-provider-BihII94U.mjs} +3 -3
- package/dist/injected-wallet-provider-BihII94U.mjs.map +1 -0
- package/dist/{injected-wallet-provider-Bps6a9IP.mjs → injected-wallet-provider-CNYAynIB.mjs} +3 -3
- package/dist/injected-wallet-provider-CNYAynIB.mjs.map +1 -0
- package/dist/{injected-wallet-provider-BUvN5Y6_.js → injected-wallet-provider-CVeZgfEt.js} +3 -3
- package/dist/injected-wallet-provider-CVeZgfEt.js.map +1 -0
- package/dist/{injected-wallet-provider-7ep-jcal.js → injected-wallet-provider-CmXqreEE.js} +3 -3
- package/dist/injected-wallet-provider-CmXqreEE.js.map +1 -0
- package/dist/onramp.d.ts +30 -0
- package/package.json +2 -2
- package/dist/email-auth-provider-BHtR1H_E.js.map +0 -1
- package/dist/email-auth-provider-BlJI-8w9.js.map +0 -1
- package/dist/email-auth-provider-CX7foEhA.mjs.map +0 -1
- package/dist/email-auth-provider-CfNSS8Du.mjs.map +0 -1
- package/dist/guest-auth-provider-BPXDJoEQ.js.map +0 -1
- package/dist/guest-auth-provider-BRjJV8Zq.js.map +0 -1
- package/dist/guest-auth-provider-DJmuReVa.mjs.map +0 -1
- package/dist/guest-auth-provider-DxhZ5sWN.mjs.map +0 -1
- package/dist/index-DWodlTFG.mjs.map +0 -1
- package/dist/index-MKE9tHpl.js.map +0 -1
- package/dist/index.native-CQiw9baS.mjs.map +0 -1
- package/dist/index.native-hu3o3zXU.js.map +0 -1
- package/dist/injected-evm-wallet-provider-BOPzdm7E.js.map +0 -1
- package/dist/injected-evm-wallet-provider-CnJRLE8P.mjs.map +0 -1
- package/dist/injected-evm-wallet-provider-DCGnUedJ.mjs.map +0 -1
- package/dist/injected-evm-wallet-provider-Xbt2CUPi.js.map +0 -1
- package/dist/injected-wallet-provider-7ep-jcal.js.map +0 -1
- package/dist/injected-wallet-provider-BUvN5Y6_.js.map +0 -1
- package/dist/injected-wallet-provider-Bps6a9IP.mjs.map +0 -1
- package/dist/injected-wallet-provider-Dg3MieTq.mjs.map +0 -1
|
@@ -3475,7 +3475,7 @@ const EMBEDDED_WALLET_UNSUPPORTED = 'Unsupported for embedded smart wallets —
|
|
|
3475
3475
|
const NO_EMBEDDED_WALLET = 'This login has no embedded wallet. Enable `"auth": { "wallets": true }` in ' +
|
|
3476
3476
|
'the app policy so email logins get a non-custodial wallet (@user.address), ' +
|
|
3477
3477
|
'then sign from a user gesture.';
|
|
3478
|
-
function hasDOM$
|
|
3478
|
+
function hasDOM$5() {
|
|
3479
3479
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
3480
3480
|
}
|
|
3481
3481
|
function decodeJwt$1(token) {
|
|
@@ -3535,7 +3535,7 @@ let requestSeq$1 = 0;
|
|
|
3535
3535
|
* wallet's owner, and validates that the wallet address matches the account.
|
|
3536
3536
|
*/
|
|
3537
3537
|
async function signViaSignerPopup(action) {
|
|
3538
|
-
if (!hasDOM$
|
|
3538
|
+
if (!hasDOM$5()) {
|
|
3539
3539
|
throw new Error('Embedded-wallet signing is only available in the browser (popup-based).');
|
|
3540
3540
|
}
|
|
3541
3541
|
const isEvm = action.kind === 'evmTransaction';
|
|
@@ -3711,7 +3711,7 @@ const STORED_AUTH_METHOD_KEY$1 = 'bounded_last_auth_method';
|
|
|
3711
3711
|
// not by `typeof window` (truthy on RN). OIDC redirect/popup is web-only, but the
|
|
3712
3712
|
// session it mints is read back through this same selector everywhere.
|
|
3713
3713
|
const sessionManager = core.getActiveSessionManager;
|
|
3714
|
-
function hasDOM$
|
|
3714
|
+
function hasDOM$4() {
|
|
3715
3715
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
3716
3716
|
}
|
|
3717
3717
|
function decodeJwt(token) {
|
|
@@ -3742,7 +3742,7 @@ const oidcProviderSingleton = {
|
|
|
3742
3742
|
const idToken = sessionManager().getIdToken();
|
|
3743
3743
|
return idToken ? userFromIdToken(idToken) : null;
|
|
3744
3744
|
},
|
|
3745
|
-
async logout() { sessionManager().clearSession(); },
|
|
3745
|
+
async logout() { await sessionManager().clearSession(); },
|
|
3746
3746
|
async signMessage(_message) {
|
|
3747
3747
|
throw new Error(hasEmbeddedWallet() ? EMBEDDED_WALLET_UNSUPPORTED : OIDC_NO_WALLET);
|
|
3748
3748
|
},
|
|
@@ -3851,7 +3851,7 @@ async function buildAuthorize(opts) {
|
|
|
3851
3851
|
throw new Error('appId is not configured (init the SDK with your appId)');
|
|
3852
3852
|
// Web: default to the current page so callers don't have to pass redirectUri. Native has no
|
|
3853
3853
|
// window — it MUST pass an https universal link (the system auth session needs a real URL).
|
|
3854
|
-
const redirectUri = opts.redirectUri || (hasDOM$
|
|
3854
|
+
const redirectUri = opts.redirectUri || (hasDOM$4() ? window.location.origin + window.location.pathname : undefined);
|
|
3855
3855
|
if (!redirectUri)
|
|
3856
3856
|
throw new Error('redirectUri is required on React Native — pass the https universal link the app owner registered.');
|
|
3857
3857
|
const { verifier, challenge } = await makePkce();
|
|
@@ -3959,7 +3959,7 @@ async function runNativeLogin(opts) {
|
|
|
3959
3959
|
async function loginWithRedirect(opts) {
|
|
3960
3960
|
if (isNative())
|
|
3961
3961
|
return runNativeLogin(opts);
|
|
3962
|
-
if (!hasDOM$
|
|
3962
|
+
if (!hasDOM$4())
|
|
3963
3963
|
throw new Error('loginWithRedirect requires a browser or a configured React Native platform');
|
|
3964
3964
|
const { url, pkce } = await buildAuthorize(opts);
|
|
3965
3965
|
// Stash the verifier + state so the redirect_uri page can finish the exchange. sessionStorage
|
|
@@ -3975,7 +3975,7 @@ async function loginWithRedirect(opts) {
|
|
|
3975
3975
|
* loginWithRedirect() (which resolves with the User), so there is no separate redirect
|
|
3976
3976
|
* page to finish from. Calling it on RN is harmless. */
|
|
3977
3977
|
async function completeLoginFromRedirect() {
|
|
3978
|
-
if (!hasDOM$
|
|
3978
|
+
if (!hasDOM$4())
|
|
3979
3979
|
return null;
|
|
3980
3980
|
const url = new URL(window.location.href);
|
|
3981
3981
|
const code = url.searchParams.get('code');
|
|
@@ -4021,7 +4021,7 @@ async function completeLoginFromRedirect() {
|
|
|
4021
4021
|
* redirect_uri page posts the code back. The redirect_uri page just calls the usual
|
|
4022
4022
|
* completeLoginFromRedirect() (which auto-detects the popup) — no separate call needed. */
|
|
4023
4023
|
async function loginWithPopup(opts) {
|
|
4024
|
-
if (!hasDOM$
|
|
4024
|
+
if (!hasDOM$4())
|
|
4025
4025
|
throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
|
|
4026
4026
|
// Open synchronously, before PKCE/config awaits consume the click's user-
|
|
4027
4027
|
// activation window. Opening only after buildAuthorize() intermittently
|
|
@@ -4161,7 +4161,7 @@ async function loginWithPopup(opts) {
|
|
|
4161
4161
|
/** Call this on the redirect_uri page when login was opened via loginWithPopup(): posts the
|
|
4162
4162
|
* code back to the opener and closes. (For the redirect variant use completeLoginFromRedirect.) */
|
|
4163
4163
|
function completeLoginInPopup(openerOrigin) {
|
|
4164
|
-
if (!hasDOM$
|
|
4164
|
+
if (!hasDOM$4() || !window.opener)
|
|
4165
4165
|
return;
|
|
4166
4166
|
const url = new URL(window.location.href);
|
|
4167
4167
|
const code = url.searchParams.get('code');
|
|
@@ -4390,15 +4390,20 @@ function authProviderConfigKey(config) {
|
|
|
4390
4390
|
* so both web (WebSessionManager) and RN (ReactNativeSessionManager) sessions
|
|
4391
4391
|
* are properly cleared.
|
|
4392
4392
|
*/
|
|
4393
|
-
function clearIncompatibleSession() {
|
|
4393
|
+
async function clearIncompatibleSession() {
|
|
4394
4394
|
if (getStoredAuthMethod() === currentAuthMethod) {
|
|
4395
4395
|
return false;
|
|
4396
4396
|
}
|
|
4397
4397
|
// Clear both managers: on web the RN manager is a no-op (not configured),
|
|
4398
4398
|
// and on RN the web manager is a no-op (no localStorage).
|
|
4399
|
-
|
|
4399
|
+
//
|
|
4400
|
+
// AWAITED. Session removal is serialized through a cross-tab lock now, so a
|
|
4401
|
+
// fire-and-forget call would let init() reach setCurrentUser while the old
|
|
4402
|
+
// credential was still readable — and a request issued in that gap would
|
|
4403
|
+
// authenticate as the session we are in the middle of discarding.
|
|
4404
|
+
await core.WebSessionManager.clearSession();
|
|
4400
4405
|
try {
|
|
4401
|
-
core.ReactNativeSessionManager.clearSession();
|
|
4406
|
+
await core.ReactNativeSessionManager.clearSession();
|
|
4402
4407
|
}
|
|
4403
4408
|
catch ( /* not configured on web */_a) { /* not configured on web */ }
|
|
4404
4409
|
setStoredAuthMethod(null);
|
|
@@ -4531,7 +4536,7 @@ async function getAuthProvider(config) {
|
|
|
4531
4536
|
// manager as legacy email sessions. Human login should be started
|
|
4532
4537
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
4533
4538
|
// logout surface for those sessions.
|
|
4534
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-
|
|
4539
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-N-dfsNnE.js'); })).EmailAuthProvider();
|
|
4535
4540
|
break;
|
|
4536
4541
|
case "wallet":
|
|
4537
4542
|
case "phantom": {
|
|
@@ -4550,7 +4555,7 @@ async function getAuthProvider(config) {
|
|
|
4550
4555
|
if (!isWalletLoginEnabled(config)) {
|
|
4551
4556
|
throw walletLoginNotEnabledError(authMethod);
|
|
4552
4557
|
}
|
|
4553
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
4558
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-CVeZgfEt.js'); });
|
|
4554
4559
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
4555
4560
|
break;
|
|
4556
4561
|
}
|
|
@@ -4563,7 +4568,7 @@ async function getAuthProvider(config) {
|
|
|
4563
4568
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
4564
4569
|
// to point at a specific wallet or set chainId/domain.
|
|
4565
4570
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
4566
|
-
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-
|
|
4571
|
+
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-CItxws1D.js'); });
|
|
4567
4572
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
4568
4573
|
break;
|
|
4569
4574
|
}
|
|
@@ -4591,7 +4596,7 @@ async function getAuthProvider(config) {
|
|
|
4591
4596
|
break;
|
|
4592
4597
|
case "guest":
|
|
4593
4598
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
4594
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
4599
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-BFodq9Rc.js'); })).GuestAuthProvider();
|
|
4595
4600
|
break;
|
|
4596
4601
|
}
|
|
4597
4602
|
if (!currentAuthProvider) {
|
|
@@ -4647,7 +4652,7 @@ async function signInAnonymously() {
|
|
|
4647
4652
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
4648
4653
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
4649
4654
|
// so bundle-splitting can see it.
|
|
4650
|
-
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
4655
|
+
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-BFodq9Rc.js'); })).GuestAuthProvider();
|
|
4651
4656
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
4652
4657
|
const commit = (user) => {
|
|
4653
4658
|
// No await/interleaving inside this block: provider/method/config/marker
|
|
@@ -4689,7 +4694,7 @@ async function signInAnonymously() {
|
|
|
4689
4694
|
}
|
|
4690
4695
|
catch (_b) {
|
|
4691
4696
|
try {
|
|
4692
|
-
core.getActiveSessionManager().clearSession();
|
|
4697
|
+
await core.getActiveSessionManager().clearSession();
|
|
4693
4698
|
}
|
|
4694
4699
|
catch ( /* fail closed below */_c) { /* fail closed below */ }
|
|
4695
4700
|
}
|
|
@@ -4798,7 +4803,7 @@ async function loginWithWallet(options) {
|
|
|
4798
4803
|
? Object.assign(Object.assign({}, base), { getProvider: options.getProvider }) : base;
|
|
4799
4804
|
const rpcUrl = normalizeSolanaRpcUrl(cfg.rpcUrl);
|
|
4800
4805
|
const network = getConfiguredSolanaNetwork(cfg);
|
|
4801
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
4806
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-CVeZgfEt.js'); });
|
|
4802
4807
|
let provider = new InjectedWalletProvider(injectedConfig, rpcUrl, network);
|
|
4803
4808
|
if (coreConfig.chain === 'offchain')
|
|
4804
4809
|
provider = new OffchainAuthProvider(provider);
|
|
@@ -4972,6 +4977,22 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4972
4977
|
signInAnonymously: signInAnonymously
|
|
4973
4978
|
});
|
|
4974
4979
|
|
|
4980
|
+
/**
|
|
4981
|
+
* Subscribed once per process, not per init(): re-registering on every init would
|
|
4982
|
+
* stack duplicate handlers on repeated initialization.
|
|
4983
|
+
*/
|
|
4984
|
+
let sessionClearedBridgeRegistered = false;
|
|
4985
|
+
function registerSessionClearedBridge() {
|
|
4986
|
+
if (sessionClearedBridgeRegistered)
|
|
4987
|
+
return;
|
|
4988
|
+
sessionClearedBridgeRegistered = true;
|
|
4989
|
+
core.onSessionCleared(() => {
|
|
4990
|
+
// Core fires this only when storage was ACTUALLY cleared, never on a
|
|
4991
|
+
// transient refresh failure that preserved the session — so this cannot
|
|
4992
|
+
// sign anyone out over a network blip.
|
|
4993
|
+
setCurrentUser(null);
|
|
4994
|
+
});
|
|
4995
|
+
}
|
|
4975
4996
|
/**
|
|
4976
4997
|
* Read the active session's idToken synchronously from whichever store is live
|
|
4977
4998
|
* for this runtime (WebSessionManager on web, ReactNativeSessionManager on RN —
|
|
@@ -5029,6 +5050,15 @@ async function init(newConfig) {
|
|
|
5029
5050
|
// setting it here makes "no flash" the SDK's default behavior for every consumer.
|
|
5030
5051
|
setAuthLoading(true);
|
|
5031
5052
|
try {
|
|
5053
|
+
// Bridge core's "the stored session is gone" signal into SDK auth state.
|
|
5054
|
+
//
|
|
5055
|
+
// Core cannot import this package, and a session can die deep inside a
|
|
5056
|
+
// session manager (dead refresh token, rejected refresh, app-id mismatch).
|
|
5057
|
+
// Before this, setCurrentUser(null) was only ever called by logout() and
|
|
5058
|
+
// init(), so storage could be wiped while `currentUser` stayed populated —
|
|
5059
|
+
// onAuthStateChanged never fired, and every consumer UI went on showing a
|
|
5060
|
+
// connected wallet for a session the server no longer knew about.
|
|
5061
|
+
registerSessionClearedBridge();
|
|
5032
5062
|
// Get auth provider first
|
|
5033
5063
|
authProviderInstance = await getAuthProvider(newConfig);
|
|
5034
5064
|
// Initialize config with auth provider
|
|
@@ -5045,7 +5075,12 @@ async function init(newConfig) {
|
|
|
5045
5075
|
let user = await authProviderInstance.restoreSession();
|
|
5046
5076
|
// If a session exists but was created before auth method tracking (legacy session),
|
|
5047
5077
|
// clear it to avoid mismatches when the app switches auth methods (e.g. email → phantom)
|
|
5048
|
-
|
|
5078
|
+
//
|
|
5079
|
+
// AWAITED: the clear is serialized through a cross-tab lock now, and an
|
|
5080
|
+
// unawaited call would return a Promise (always truthy) — nulling the user
|
|
5081
|
+
// unconditionally AND letting setCurrentUser run while the old credential
|
|
5082
|
+
// was still in storage.
|
|
5083
|
+
if (user && await clearIncompatibleSession()) {
|
|
5049
5084
|
user = null;
|
|
5050
5085
|
}
|
|
5051
5086
|
setCurrentUser(user);
|
|
@@ -5163,7 +5198,7 @@ function setAuthProviderInstance(provider) {
|
|
|
5163
5198
|
// The modal is a warm singleton: it stays mounted (hidden) between uses so a
|
|
5164
5199
|
// second open - or a signature right after login - is instant and, when it is
|
|
5165
5200
|
// already open, a clean in-place view swap rather than a reopen.
|
|
5166
|
-
function hasDOM$
|
|
5201
|
+
function hasDOM$3() {
|
|
5167
5202
|
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
5168
5203
|
}
|
|
5169
5204
|
const OVERLAY_CSS = `
|
|
@@ -5385,7 +5420,7 @@ function detachIframe(m) {
|
|
|
5385
5420
|
// no-op if already present or off-DOM. Fonts loaded here match the hosted auth page.
|
|
5386
5421
|
const FONTS_HREF = "https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,500&family=Schibsted+Grotesk:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap";
|
|
5387
5422
|
function ensureFonts() {
|
|
5388
|
-
if (!hasDOM$
|
|
5423
|
+
if (!hasDOM$3())
|
|
5389
5424
|
return;
|
|
5390
5425
|
if (document.querySelector('link[data-bounded-fonts="1"]'))
|
|
5391
5426
|
return;
|
|
@@ -5691,7 +5726,7 @@ function discoverStandardWallets() {
|
|
|
5691
5726
|
return out;
|
|
5692
5727
|
}
|
|
5693
5728
|
|
|
5694
|
-
function hasDOM$
|
|
5729
|
+
function hasDOM$2() {
|
|
5695
5730
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
5696
5731
|
}
|
|
5697
5732
|
async function signerOrigin() {
|
|
@@ -5768,7 +5803,7 @@ function sealOtpInIframe(code, otpEncryptionTargetBundle) {
|
|
|
5768
5803
|
* step needs the signer iframe); on React Native use loginWithRedirect() instead.
|
|
5769
5804
|
*/
|
|
5770
5805
|
async function startTurnkeyEmailLogin(email) {
|
|
5771
|
-
if (!hasDOM$
|
|
5806
|
+
if (!hasDOM$2()) {
|
|
5772
5807
|
throw new Error('Turnkey-native email login is web-only - on React Native use loginWithRedirect()');
|
|
5773
5808
|
}
|
|
5774
5809
|
const trimmed = email.trim();
|
|
@@ -5957,7 +5992,7 @@ function el(tag, cls, text) {
|
|
|
5957
5992
|
*/
|
|
5958
5993
|
async function openBoundedWidget(opts = {}) {
|
|
5959
5994
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
5960
|
-
if (!hasDOM$
|
|
5995
|
+
if (!hasDOM$3()) {
|
|
5961
5996
|
throw new Error("openBoundedWidget is web-only - on React Native use loginWithRedirect()");
|
|
5962
5997
|
}
|
|
5963
5998
|
// Imported lazily to avoid a static cycle with the auth index barrel.
|
|
@@ -7064,7 +7099,7 @@ async function deserializeTransaction(tx) {
|
|
|
7064
7099
|
* (Safari cross-origin create) or cannot be mounted.
|
|
7065
7100
|
*/
|
|
7066
7101
|
async function runWidget(url, signerOrigin, ex, popupFallback) {
|
|
7067
|
-
if (!hasDOM$
|
|
7102
|
+
if (!hasDOM$3())
|
|
7068
7103
|
return popupFallback();
|
|
7069
7104
|
const m = getModal();
|
|
7070
7105
|
const requestId = String(ex.request.requestId);
|
|
@@ -7173,7 +7208,7 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
|
|
|
7173
7208
|
// ONE ORIGIN, ONE PASSKEY: a WebAuthn passkey is bound to a single origin, so ALL
|
|
7174
7209
|
// Bounded apps (any subdomain / custom domain) sign through this one origin - giving
|
|
7175
7210
|
// every user one wallet + one passkey that roams across every app.
|
|
7176
|
-
function hasDOM() {
|
|
7211
|
+
function hasDOM$1() {
|
|
7177
7212
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
7178
7213
|
}
|
|
7179
7214
|
// Safari (incl. iOS WebViews) is unreliable at running a WebAuthn CREATE inside a
|
|
@@ -7182,7 +7217,7 @@ function hasDOM() {
|
|
|
7182
7217
|
// There we pick the popup up front, from the original click, so enrollment is solid.
|
|
7183
7218
|
// Everywhere else the inline widget is used (buttery in-app modal).
|
|
7184
7219
|
function preferPopup() {
|
|
7185
|
-
if (!hasDOM() || typeof navigator === 'undefined')
|
|
7220
|
+
if (!hasDOM$1() || typeof navigator === 'undefined')
|
|
7186
7221
|
return true;
|
|
7187
7222
|
const ua = navigator.userAgent || '';
|
|
7188
7223
|
return /^((?!chrome|android|crios|fxios|edg|edga|opr).)*safari/i.test(ua);
|
|
@@ -7299,7 +7334,7 @@ async function runPopup(url, signerOrigin, ex) {
|
|
|
7299
7334
|
* Use this to learn the fee-payer address BEFORE building a transaction to sign.
|
|
7300
7335
|
*/
|
|
7301
7336
|
async function getOrCreateTurnkeyWallet() {
|
|
7302
|
-
if (!hasDOM())
|
|
7337
|
+
if (!hasDOM$1())
|
|
7303
7338
|
throw new Error('Turnkey embedded wallets are only available in the browser (popup-based).');
|
|
7304
7339
|
const { url, origin } = await turnkeySignerPage();
|
|
7305
7340
|
const requestId = `tkcreate_${Date.now()}_${++requestSeq}`;
|
|
@@ -7323,7 +7358,7 @@ async function getOrCreateTurnkeyWallet() {
|
|
|
7323
7358
|
* signatures are just a passkey approval.
|
|
7324
7359
|
*/
|
|
7325
7360
|
async function signSolanaMessageViaTurnkey(message) {
|
|
7326
|
-
if (!hasDOM()) {
|
|
7361
|
+
if (!hasDOM$1()) {
|
|
7327
7362
|
throw new Error('Turnkey embedded-wallet signing is only available in the browser (popup-based).');
|
|
7328
7363
|
}
|
|
7329
7364
|
const { url, origin } = await turnkeySignerPage();
|
|
@@ -7340,6 +7375,109 @@ async function signSolanaMessageViaTurnkey(message) {
|
|
|
7340
7375
|
});
|
|
7341
7376
|
}
|
|
7342
7377
|
|
|
7378
|
+
// bounded.onramp() - fund the signed-in user's wallet with Coinbase Onramp.
|
|
7379
|
+
//
|
|
7380
|
+
// Web-only. Opens Coinbase's hosted checkout (pay.coinbase.com) in a popup
|
|
7381
|
+
// (new-tab fallback) using a single-use session token minted by the Bounded
|
|
7382
|
+
// platform at POST <origin>/__bounded/onramp/session on the app's own origin.
|
|
7383
|
+
// The platform holds the Coinbase credential; the app never sees it. The
|
|
7384
|
+
// session is bound server-side to the caller's verified Bounded JWT, and the
|
|
7385
|
+
// destination defaults to that user's embedded wallet.
|
|
7386
|
+
//
|
|
7387
|
+
// Works on Bounded-served origins (<app>.bounded.page / custom domains). On a
|
|
7388
|
+
// local dev origin the session endpoint does not exist; we fail with a clear
|
|
7389
|
+
// error rather than guessing a host.
|
|
7390
|
+
function hasDOM() {
|
|
7391
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
7392
|
+
}
|
|
7393
|
+
/**
|
|
7394
|
+
* Open Coinbase Onramp for the signed-in user. Resolves when the popup closes.
|
|
7395
|
+
* Call from a click handler - popup blockers require user activation.
|
|
7396
|
+
*/
|
|
7397
|
+
async function onramp(options = {}) {
|
|
7398
|
+
var _a, _b, _c;
|
|
7399
|
+
if (!hasDOM())
|
|
7400
|
+
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');
|
|
7411
|
+
// Open the window synchronously so the click's user-activation window is not
|
|
7412
|
+
// consumed by the fetch below (same hard-won pattern as loginWithPopup).
|
|
7413
|
+
let popup = null;
|
|
7414
|
+
if (!options.newTab) {
|
|
7415
|
+
const w = options.width || 460;
|
|
7416
|
+
const h = options.height || 720;
|
|
7417
|
+
const left = window.screenX + (window.outerWidth - w) / 2;
|
|
7418
|
+
const top = window.screenY + (window.outerHeight - h) / 2;
|
|
7419
|
+
popup = window.open('', 'bounded-onramp', `width=${w},height=${h},left=${left},top=${top}`);
|
|
7420
|
+
}
|
|
7421
|
+
let session;
|
|
7422
|
+
try {
|
|
7423
|
+
const res = await fetch(`${window.location.origin}/__bounded/onramp/session`, {
|
|
7424
|
+
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 } : {}))),
|
|
7427
|
+
});
|
|
7428
|
+
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 */ }
|
|
7434
|
+
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');
|
|
7436
|
+
}
|
|
7437
|
+
throw new Error(`onramp(): session mint failed (${res.status}${detail ? `: ${detail}` : ''})`);
|
|
7438
|
+
}
|
|
7439
|
+
session = (await res.json());
|
|
7440
|
+
}
|
|
7441
|
+
catch (error) {
|
|
7442
|
+
try {
|
|
7443
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
7444
|
+
}
|
|
7445
|
+
catch ( /* ignore */_e) { /* ignore */ }
|
|
7446
|
+
throw error;
|
|
7447
|
+
}
|
|
7448
|
+
if (popup) {
|
|
7449
|
+
try {
|
|
7450
|
+
popup.location.replace(session.url);
|
|
7451
|
+
}
|
|
7452
|
+
catch (_f) {
|
|
7453
|
+
try {
|
|
7454
|
+
popup.location.href = session.url;
|
|
7455
|
+
}
|
|
7456
|
+
catch (_g) {
|
|
7457
|
+
try {
|
|
7458
|
+
popup.close();
|
|
7459
|
+
}
|
|
7460
|
+
catch ( /* ignore */_h) { /* ignore */ }
|
|
7461
|
+
throw new Error('onramp(): popup failed to navigate - retry with { newTab: true }');
|
|
7462
|
+
}
|
|
7463
|
+
}
|
|
7464
|
+
return await new Promise((resolve) => {
|
|
7465
|
+
const timer = setInterval(() => {
|
|
7466
|
+
if (popup.closed) {
|
|
7467
|
+
clearInterval(timer);
|
|
7468
|
+
resolve({ status: 'closed', address: session.address, asset: session.asset });
|
|
7469
|
+
}
|
|
7470
|
+
}, 500);
|
|
7471
|
+
});
|
|
7472
|
+
}
|
|
7473
|
+
// New-tab path (popup was blocked or explicitly requested): cross-origin tab
|
|
7474
|
+
// close is not observable, so resolve immediately.
|
|
7475
|
+
const tab = window.open(session.url, '_blank');
|
|
7476
|
+
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 };
|
|
7479
|
+
}
|
|
7480
|
+
|
|
7343
7481
|
/**
|
|
7344
7482
|
* Extracts a human-readable error message from Solana transaction logs.
|
|
7345
7483
|
*/
|
|
@@ -7469,7 +7607,7 @@ class PrivyExpoProvider {
|
|
|
7469
7607
|
return { provider: this, address: session.address };
|
|
7470
7608
|
}
|
|
7471
7609
|
// Stale session — clear and continue to fresh login flow
|
|
7472
|
-
core.getActiveSessionManager().clearSession();
|
|
7610
|
+
await core.getActiveSessionManager().clearSession();
|
|
7473
7611
|
}
|
|
7474
7612
|
// Trigger Privy login
|
|
7475
7613
|
const privyUser = await this.privyMethods.login();
|
|
@@ -7650,7 +7788,7 @@ class PrivyExpoProvider {
|
|
|
7650
7788
|
if ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.isAuthenticated) {
|
|
7651
7789
|
await this.privyMethods.logout();
|
|
7652
7790
|
}
|
|
7653
|
-
core.getActiveSessionManager().clearSession();
|
|
7791
|
+
await core.getActiveSessionManager().clearSession();
|
|
7654
7792
|
}
|
|
7655
7793
|
async getNativeMethods() {
|
|
7656
7794
|
return this.privyMethods;
|
|
@@ -7850,6 +7988,7 @@ exports.logout = logout;
|
|
|
7850
7988
|
exports.normalizeSolanaRpcUrl = normalizeSolanaRpcUrl;
|
|
7851
7989
|
exports.onAuthLoadingChanged = onAuthLoadingChanged;
|
|
7852
7990
|
exports.onAuthStateChanged = onAuthStateChanged;
|
|
7991
|
+
exports.onramp = onramp;
|
|
7853
7992
|
exports.openBoundedWidget = openBoundedWidget;
|
|
7854
7993
|
exports.requestEip6963Providers = requestEip6963Providers;
|
|
7855
7994
|
exports.resolveSolanaRpcUrl = resolveSolanaRpcUrl;
|
|
@@ -7862,4 +8001,4 @@ exports.startTurnkeyEmailLogin = startTurnkeyEmailLogin;
|
|
|
7862
8001
|
exports.useAuth = useAuth;
|
|
7863
8002
|
exports.useBuildRun = useBuildRun;
|
|
7864
8003
|
exports.useQuery = useQuery;
|
|
7865
|
-
//# sourceMappingURL=index-
|
|
8004
|
+
//# sourceMappingURL=index-uu8hKP-p.js.map
|