@bounded-sh/client 0.0.57 → 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-Bmah1GWS.mjs → email-auth-provider-DhAMOILG.mjs} +3 -3
- package/dist/email-auth-provider-DhAMOILG.mjs.map +1 -0
- package/dist/{email-auth-provider-8k8iBIQL.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-D6h4eAtx.mjs → guest-auth-provider-B78Ugfar.mjs} +7 -7
- package/dist/guest-auth-provider-B78Ugfar.mjs.map +1 -0
- package/dist/{guest-auth-provider-BjfjrpdW.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-C7rOe6B2.mjs → index-SHt4VZZV.mjs} +181 -40
- package/dist/index-SHt4VZZV.mjs.map +1 -0
- package/dist/{index-CnObYQhV.js → index-uu8hKP-p.js} +180 -38
- 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-CcwS6p3o.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-DIWeWiAN.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-CFnqSsHy.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-B_jQFifE.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-8k8iBIQL.js.map +0 -1
- package/dist/email-auth-provider-BlJI-8w9.js.map +0 -1
- package/dist/email-auth-provider-Bmah1GWS.mjs.map +0 -1
- package/dist/email-auth-provider-CfNSS8Du.mjs.map +0 -1
- package/dist/guest-auth-provider-BRjJV8Zq.js.map +0 -1
- package/dist/guest-auth-provider-BjfjrpdW.js.map +0 -1
- package/dist/guest-auth-provider-D6h4eAtx.mjs.map +0 -1
- package/dist/guest-auth-provider-DxhZ5sWN.mjs.map +0 -1
- package/dist/index-C7rOe6B2.mjs.map +0 -1
- package/dist/index-CnObYQhV.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-CcwS6p3o.js.map +0 -1
- package/dist/injected-evm-wallet-provider-DCGnUedJ.mjs.map +0 -1
- package/dist/injected-evm-wallet-provider-DIWeWiAN.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-B_jQFifE.js.map +0 -1
- package/dist/injected-wallet-provider-Bps6a9IP.mjs.map +0 -1
- package/dist/injected-wallet-provider-CFnqSsHy.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertCanonicalBoundedRuntimeWriteCalldata, getActiveSessionManager, getConfig, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, reconnectWithNewAuth, deriveUserIdentityFromIdToken, subscribe, getIdToken as getIdToken$1, convertRemainingAccounts, buildSetDocumentsTransaction, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
|
|
1
|
+
import { assertCanonicalBoundedRuntimeWriteCalldata, getActiveSessionManager, getConfig, WebSessionManager, ReactNativeSessionManager, revokeSession, init as init$1, onSessionCleared, reconnectWithNewAuth, deriveUserIdentityFromIdToken, subscribe, getIdToken as getIdToken$1, convertRemainingAccounts, buildSetDocumentsTransaction, genAuthNonce, genSolanaMessage, createSessionWithSignature } from '@bounded-sh/core';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -3454,7 +3454,7 @@ const EMBEDDED_WALLET_UNSUPPORTED = 'Unsupported for embedded smart wallets —
|
|
|
3454
3454
|
const NO_EMBEDDED_WALLET = 'This login has no embedded wallet. Enable `"auth": { "wallets": true }` in ' +
|
|
3455
3455
|
'the app policy so email logins get a non-custodial wallet (@user.address), ' +
|
|
3456
3456
|
'then sign from a user gesture.';
|
|
3457
|
-
function hasDOM$
|
|
3457
|
+
function hasDOM$5() {
|
|
3458
3458
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
3459
3459
|
}
|
|
3460
3460
|
function decodeJwt$1(token) {
|
|
@@ -3514,7 +3514,7 @@ let requestSeq$1 = 0;
|
|
|
3514
3514
|
* wallet's owner, and validates that the wallet address matches the account.
|
|
3515
3515
|
*/
|
|
3516
3516
|
async function signViaSignerPopup(action) {
|
|
3517
|
-
if (!hasDOM$
|
|
3517
|
+
if (!hasDOM$5()) {
|
|
3518
3518
|
throw new Error('Embedded-wallet signing is only available in the browser (popup-based).');
|
|
3519
3519
|
}
|
|
3520
3520
|
const isEvm = action.kind === 'evmTransaction';
|
|
@@ -3690,7 +3690,7 @@ const STORED_AUTH_METHOD_KEY$1 = 'bounded_last_auth_method';
|
|
|
3690
3690
|
// not by `typeof window` (truthy on RN). OIDC redirect/popup is web-only, but the
|
|
3691
3691
|
// session it mints is read back through this same selector everywhere.
|
|
3692
3692
|
const sessionManager = getActiveSessionManager;
|
|
3693
|
-
function hasDOM$
|
|
3693
|
+
function hasDOM$4() {
|
|
3694
3694
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
3695
3695
|
}
|
|
3696
3696
|
function decodeJwt(token) {
|
|
@@ -3721,7 +3721,7 @@ const oidcProviderSingleton = {
|
|
|
3721
3721
|
const idToken = sessionManager().getIdToken();
|
|
3722
3722
|
return idToken ? userFromIdToken(idToken) : null;
|
|
3723
3723
|
},
|
|
3724
|
-
async logout() { sessionManager().clearSession(); },
|
|
3724
|
+
async logout() { await sessionManager().clearSession(); },
|
|
3725
3725
|
async signMessage(_message) {
|
|
3726
3726
|
throw new Error(hasEmbeddedWallet() ? EMBEDDED_WALLET_UNSUPPORTED : OIDC_NO_WALLET);
|
|
3727
3727
|
},
|
|
@@ -3830,7 +3830,7 @@ async function buildAuthorize(opts) {
|
|
|
3830
3830
|
throw new Error('appId is not configured (init the SDK with your appId)');
|
|
3831
3831
|
// Web: default to the current page so callers don't have to pass redirectUri. Native has no
|
|
3832
3832
|
// window — it MUST pass an https universal link (the system auth session needs a real URL).
|
|
3833
|
-
const redirectUri = opts.redirectUri || (hasDOM$
|
|
3833
|
+
const redirectUri = opts.redirectUri || (hasDOM$4() ? window.location.origin + window.location.pathname : undefined);
|
|
3834
3834
|
if (!redirectUri)
|
|
3835
3835
|
throw new Error('redirectUri is required on React Native — pass the https universal link the app owner registered.');
|
|
3836
3836
|
const { verifier, challenge } = await makePkce();
|
|
@@ -3938,7 +3938,7 @@ async function runNativeLogin(opts) {
|
|
|
3938
3938
|
async function loginWithRedirect(opts) {
|
|
3939
3939
|
if (isNative())
|
|
3940
3940
|
return runNativeLogin(opts);
|
|
3941
|
-
if (!hasDOM$
|
|
3941
|
+
if (!hasDOM$4())
|
|
3942
3942
|
throw new Error('loginWithRedirect requires a browser or a configured React Native platform');
|
|
3943
3943
|
const { url, pkce } = await buildAuthorize(opts);
|
|
3944
3944
|
// Stash the verifier + state so the redirect_uri page can finish the exchange. sessionStorage
|
|
@@ -3954,7 +3954,7 @@ async function loginWithRedirect(opts) {
|
|
|
3954
3954
|
* loginWithRedirect() (which resolves with the User), so there is no separate redirect
|
|
3955
3955
|
* page to finish from. Calling it on RN is harmless. */
|
|
3956
3956
|
async function completeLoginFromRedirect() {
|
|
3957
|
-
if (!hasDOM$
|
|
3957
|
+
if (!hasDOM$4())
|
|
3958
3958
|
return null;
|
|
3959
3959
|
const url = new URL(window.location.href);
|
|
3960
3960
|
const code = url.searchParams.get('code');
|
|
@@ -4000,7 +4000,7 @@ async function completeLoginFromRedirect() {
|
|
|
4000
4000
|
* redirect_uri page posts the code back. The redirect_uri page just calls the usual
|
|
4001
4001
|
* completeLoginFromRedirect() (which auto-detects the popup) — no separate call needed. */
|
|
4002
4002
|
async function loginWithPopup(opts) {
|
|
4003
|
-
if (!hasDOM$
|
|
4003
|
+
if (!hasDOM$4())
|
|
4004
4004
|
throw new Error('loginWithPopup is web-only — on React Native use loginWithRedirect()');
|
|
4005
4005
|
// Open synchronously, before PKCE/config awaits consume the click's user-
|
|
4006
4006
|
// activation window. Opening only after buildAuthorize() intermittently
|
|
@@ -4140,7 +4140,7 @@ async function loginWithPopup(opts) {
|
|
|
4140
4140
|
/** Call this on the redirect_uri page when login was opened via loginWithPopup(): posts the
|
|
4141
4141
|
* code back to the opener and closes. (For the redirect variant use completeLoginFromRedirect.) */
|
|
4142
4142
|
function completeLoginInPopup(openerOrigin) {
|
|
4143
|
-
if (!hasDOM$
|
|
4143
|
+
if (!hasDOM$4() || !window.opener)
|
|
4144
4144
|
return;
|
|
4145
4145
|
const url = new URL(window.location.href);
|
|
4146
4146
|
const code = url.searchParams.get('code');
|
|
@@ -4369,15 +4369,20 @@ function authProviderConfigKey(config) {
|
|
|
4369
4369
|
* so both web (WebSessionManager) and RN (ReactNativeSessionManager) sessions
|
|
4370
4370
|
* are properly cleared.
|
|
4371
4371
|
*/
|
|
4372
|
-
function clearIncompatibleSession() {
|
|
4372
|
+
async function clearIncompatibleSession() {
|
|
4373
4373
|
if (getStoredAuthMethod() === currentAuthMethod) {
|
|
4374
4374
|
return false;
|
|
4375
4375
|
}
|
|
4376
4376
|
// Clear both managers: on web the RN manager is a no-op (not configured),
|
|
4377
4377
|
// and on RN the web manager is a no-op (no localStorage).
|
|
4378
|
-
|
|
4378
|
+
//
|
|
4379
|
+
// AWAITED. Session removal is serialized through a cross-tab lock now, so a
|
|
4380
|
+
// fire-and-forget call would let init() reach setCurrentUser while the old
|
|
4381
|
+
// credential was still readable — and a request issued in that gap would
|
|
4382
|
+
// authenticate as the session we are in the middle of discarding.
|
|
4383
|
+
await WebSessionManager.clearSession();
|
|
4379
4384
|
try {
|
|
4380
|
-
ReactNativeSessionManager.clearSession();
|
|
4385
|
+
await ReactNativeSessionManager.clearSession();
|
|
4381
4386
|
}
|
|
4382
4387
|
catch ( /* not configured on web */_a) { /* not configured on web */ }
|
|
4383
4388
|
setStoredAuthMethod(null);
|
|
@@ -4510,7 +4515,7 @@ async function getAuthProvider(config) {
|
|
|
4510
4515
|
// manager as legacy email sessions. Human login should be started
|
|
4511
4516
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
4512
4517
|
// logout surface for those sessions.
|
|
4513
|
-
currentAuthProvider = new (await import('./email-auth-provider-
|
|
4518
|
+
currentAuthProvider = new (await import('./email-auth-provider-DhAMOILG.mjs')).EmailAuthProvider();
|
|
4514
4519
|
break;
|
|
4515
4520
|
case "wallet":
|
|
4516
4521
|
case "phantom": {
|
|
@@ -4529,7 +4534,7 @@ async function getAuthProvider(config) {
|
|
|
4529
4534
|
if (!isWalletLoginEnabled(config)) {
|
|
4530
4535
|
throw walletLoginNotEnabledError(authMethod);
|
|
4531
4536
|
}
|
|
4532
|
-
const { InjectedWalletProvider } = await import('./injected-wallet-provider-
|
|
4537
|
+
const { InjectedWalletProvider } = await import('./injected-wallet-provider-BihII94U.mjs');
|
|
4533
4538
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
4534
4539
|
break;
|
|
4535
4540
|
}
|
|
@@ -4542,7 +4547,7 @@ async function getAuthProvider(config) {
|
|
|
4542
4547
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
4543
4548
|
// to point at a specific wallet or set chainId/domain.
|
|
4544
4549
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
4545
|
-
const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-
|
|
4550
|
+
const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-UWvcy-LO.mjs');
|
|
4546
4551
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
4547
4552
|
break;
|
|
4548
4553
|
}
|
|
@@ -4570,7 +4575,7 @@ async function getAuthProvider(config) {
|
|
|
4570
4575
|
break;
|
|
4571
4576
|
case "guest":
|
|
4572
4577
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
4573
|
-
currentAuthProvider = new (await import('./guest-auth-provider-
|
|
4578
|
+
currentAuthProvider = new (await import('./guest-auth-provider-B78Ugfar.mjs')).GuestAuthProvider();
|
|
4574
4579
|
break;
|
|
4575
4580
|
}
|
|
4576
4581
|
if (!currentAuthProvider) {
|
|
@@ -4626,7 +4631,7 @@ async function signInAnonymously() {
|
|
|
4626
4631
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
4627
4632
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
4628
4633
|
// so bundle-splitting can see it.
|
|
4629
|
-
const provider = new (await import('./guest-auth-provider-
|
|
4634
|
+
const provider = new (await import('./guest-auth-provider-B78Ugfar.mjs')).GuestAuthProvider();
|
|
4630
4635
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
4631
4636
|
const commit = (user) => {
|
|
4632
4637
|
// No await/interleaving inside this block: provider/method/config/marker
|
|
@@ -4668,7 +4673,7 @@ async function signInAnonymously() {
|
|
|
4668
4673
|
}
|
|
4669
4674
|
catch (_b) {
|
|
4670
4675
|
try {
|
|
4671
|
-
getActiveSessionManager().clearSession();
|
|
4676
|
+
await getActiveSessionManager().clearSession();
|
|
4672
4677
|
}
|
|
4673
4678
|
catch ( /* fail closed below */_c) { /* fail closed below */ }
|
|
4674
4679
|
}
|
|
@@ -4777,7 +4782,7 @@ async function loginWithWallet(options) {
|
|
|
4777
4782
|
? Object.assign(Object.assign({}, base), { getProvider: options.getProvider }) : base;
|
|
4778
4783
|
const rpcUrl = normalizeSolanaRpcUrl(cfg.rpcUrl);
|
|
4779
4784
|
const network = getConfiguredSolanaNetwork(cfg);
|
|
4780
|
-
const { InjectedWalletProvider } = await import('./injected-wallet-provider-
|
|
4785
|
+
const { InjectedWalletProvider } = await import('./injected-wallet-provider-BihII94U.mjs');
|
|
4781
4786
|
let provider = new InjectedWalletProvider(injectedConfig, rpcUrl, network);
|
|
4782
4787
|
if (coreConfig.chain === 'offchain')
|
|
4783
4788
|
provider = new OffchainAuthProvider(provider);
|
|
@@ -4951,6 +4956,22 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
4951
4956
|
signInAnonymously: signInAnonymously
|
|
4952
4957
|
});
|
|
4953
4958
|
|
|
4959
|
+
/**
|
|
4960
|
+
* Subscribed once per process, not per init(): re-registering on every init would
|
|
4961
|
+
* stack duplicate handlers on repeated initialization.
|
|
4962
|
+
*/
|
|
4963
|
+
let sessionClearedBridgeRegistered = false;
|
|
4964
|
+
function registerSessionClearedBridge() {
|
|
4965
|
+
if (sessionClearedBridgeRegistered)
|
|
4966
|
+
return;
|
|
4967
|
+
sessionClearedBridgeRegistered = true;
|
|
4968
|
+
onSessionCleared(() => {
|
|
4969
|
+
// Core fires this only when storage was ACTUALLY cleared, never on a
|
|
4970
|
+
// transient refresh failure that preserved the session — so this cannot
|
|
4971
|
+
// sign anyone out over a network blip.
|
|
4972
|
+
setCurrentUser(null);
|
|
4973
|
+
});
|
|
4974
|
+
}
|
|
4954
4975
|
/**
|
|
4955
4976
|
* Read the active session's idToken synchronously from whichever store is live
|
|
4956
4977
|
* for this runtime (WebSessionManager on web, ReactNativeSessionManager on RN —
|
|
@@ -5008,6 +5029,15 @@ async function init(newConfig) {
|
|
|
5008
5029
|
// setting it here makes "no flash" the SDK's default behavior for every consumer.
|
|
5009
5030
|
setAuthLoading(true);
|
|
5010
5031
|
try {
|
|
5032
|
+
// Bridge core's "the stored session is gone" signal into SDK auth state.
|
|
5033
|
+
//
|
|
5034
|
+
// Core cannot import this package, and a session can die deep inside a
|
|
5035
|
+
// session manager (dead refresh token, rejected refresh, app-id mismatch).
|
|
5036
|
+
// Before this, setCurrentUser(null) was only ever called by logout() and
|
|
5037
|
+
// init(), so storage could be wiped while `currentUser` stayed populated —
|
|
5038
|
+
// onAuthStateChanged never fired, and every consumer UI went on showing a
|
|
5039
|
+
// connected wallet for a session the server no longer knew about.
|
|
5040
|
+
registerSessionClearedBridge();
|
|
5011
5041
|
// Get auth provider first
|
|
5012
5042
|
authProviderInstance = await getAuthProvider(newConfig);
|
|
5013
5043
|
// Initialize config with auth provider
|
|
@@ -5024,7 +5054,12 @@ async function init(newConfig) {
|
|
|
5024
5054
|
let user = await authProviderInstance.restoreSession();
|
|
5025
5055
|
// If a session exists but was created before auth method tracking (legacy session),
|
|
5026
5056
|
// clear it to avoid mismatches when the app switches auth methods (e.g. email → phantom)
|
|
5027
|
-
|
|
5057
|
+
//
|
|
5058
|
+
// AWAITED: the clear is serialized through a cross-tab lock now, and an
|
|
5059
|
+
// unawaited call would return a Promise (always truthy) — nulling the user
|
|
5060
|
+
// unconditionally AND letting setCurrentUser run while the old credential
|
|
5061
|
+
// was still in storage.
|
|
5062
|
+
if (user && await clearIncompatibleSession()) {
|
|
5028
5063
|
user = null;
|
|
5029
5064
|
}
|
|
5030
5065
|
setCurrentUser(user);
|
|
@@ -5142,7 +5177,7 @@ function setAuthProviderInstance(provider) {
|
|
|
5142
5177
|
// The modal is a warm singleton: it stays mounted (hidden) between uses so a
|
|
5143
5178
|
// second open - or a signature right after login - is instant and, when it is
|
|
5144
5179
|
// already open, a clean in-place view swap rather than a reopen.
|
|
5145
|
-
function hasDOM$
|
|
5180
|
+
function hasDOM$3() {
|
|
5146
5181
|
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
5147
5182
|
}
|
|
5148
5183
|
const OVERLAY_CSS = `
|
|
@@ -5364,7 +5399,7 @@ function detachIframe(m) {
|
|
|
5364
5399
|
// no-op if already present or off-DOM. Fonts loaded here match the hosted auth page.
|
|
5365
5400
|
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";
|
|
5366
5401
|
function ensureFonts() {
|
|
5367
|
-
if (!hasDOM$
|
|
5402
|
+
if (!hasDOM$3())
|
|
5368
5403
|
return;
|
|
5369
5404
|
if (document.querySelector('link[data-bounded-fonts="1"]'))
|
|
5370
5405
|
return;
|
|
@@ -5670,7 +5705,7 @@ function discoverStandardWallets() {
|
|
|
5670
5705
|
return out;
|
|
5671
5706
|
}
|
|
5672
5707
|
|
|
5673
|
-
function hasDOM$
|
|
5708
|
+
function hasDOM$2() {
|
|
5674
5709
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
5675
5710
|
}
|
|
5676
5711
|
async function signerOrigin() {
|
|
@@ -5747,7 +5782,7 @@ function sealOtpInIframe(code, otpEncryptionTargetBundle) {
|
|
|
5747
5782
|
* step needs the signer iframe); on React Native use loginWithRedirect() instead.
|
|
5748
5783
|
*/
|
|
5749
5784
|
async function startTurnkeyEmailLogin(email) {
|
|
5750
|
-
if (!hasDOM$
|
|
5785
|
+
if (!hasDOM$2()) {
|
|
5751
5786
|
throw new Error('Turnkey-native email login is web-only - on React Native use loginWithRedirect()');
|
|
5752
5787
|
}
|
|
5753
5788
|
const trimmed = email.trim();
|
|
@@ -5935,8 +5970,8 @@ function el(tag, cls, text) {
|
|
|
5935
5970
|
* run first; call from a user gesture so social/wallet popups are allowed.
|
|
5936
5971
|
*/
|
|
5937
5972
|
async function openBoundedWidget(opts = {}) {
|
|
5938
|
-
var _a, _b, _c, _d;
|
|
5939
|
-
if (!hasDOM$
|
|
5973
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
5974
|
+
if (!hasDOM$3()) {
|
|
5940
5975
|
throw new Error("openBoundedWidget is web-only - on React Native use loginWithRedirect()");
|
|
5941
5976
|
}
|
|
5942
5977
|
// Imported lazily to avoid a static cycle with the auth index barrel.
|
|
@@ -5954,6 +5989,10 @@ async function openBoundedWidget(opts = {}) {
|
|
|
5954
5989
|
? false
|
|
5955
5990
|
: ((_c = opts.wallet) !== null && _c !== void 0 ? _c : (wallets.length > 0 || authApi.isWalletLoginEnabled(initCfg)));
|
|
5956
5991
|
const authMode = (_d = opts.authMode) !== null && _d !== void 0 ? _d : authApi.resolveAuthMode(initCfg);
|
|
5992
|
+
// Widget text: per-call options win, then init() loginWidget config, then the
|
|
5993
|
+
// defaults ("Sign in" / the Bounded subline; "" suppresses the subline).
|
|
5994
|
+
const title = (_e = opts.title) !== null && _e !== void 0 ? _e : (_f = initCfg.loginWidget) === null || _f === void 0 ? void 0 : _f.title;
|
|
5995
|
+
const subtitle = (_g = opts.subtitle) !== null && _g !== void 0 ? _g : (_h = initCfg.loginWidget) === null || _h === void 0 ? void 0 : _h.subtitle;
|
|
5957
5996
|
ensureFonts();
|
|
5958
5997
|
const m = getModal();
|
|
5959
5998
|
return new Promise((resolve, reject) => {
|
|
@@ -5977,7 +6016,6 @@ async function openBoundedWidget(opts = {}) {
|
|
|
5977
6016
|
const style = el("style");
|
|
5978
6017
|
style.textContent = CARD_CSS;
|
|
5979
6018
|
const renderChoose = () => {
|
|
5980
|
-
var _a, _b;
|
|
5981
6019
|
const card = el("div", "c");
|
|
5982
6020
|
card.appendChild(style.cloneNode(true));
|
|
5983
6021
|
const x = el("button", "x", "Close");
|
|
@@ -5985,9 +6023,9 @@ async function openBoundedWidget(opts = {}) {
|
|
|
5985
6023
|
x.setAttribute("aria-label", "Close");
|
|
5986
6024
|
x.addEventListener("click", cancel);
|
|
5987
6025
|
card.appendChild(x);
|
|
5988
|
-
card.appendChild(el("h1", undefined,
|
|
5989
|
-
if (
|
|
5990
|
-
card.appendChild(el("p", "sub",
|
|
6026
|
+
card.appendChild(el("h1", undefined, title !== null && title !== void 0 ? title : "Sign in"));
|
|
6027
|
+
if (subtitle !== "") {
|
|
6028
|
+
card.appendChild(el("p", "sub", subtitle !== null && subtitle !== void 0 ? subtitle : "One account and wallet across every Bounded app."));
|
|
5991
6029
|
}
|
|
5992
6030
|
const status = el("div", "status");
|
|
5993
6031
|
const setErr = (msg) => {
|
|
@@ -7040,7 +7078,7 @@ async function deserializeTransaction(tx) {
|
|
|
7040
7078
|
* (Safari cross-origin create) or cannot be mounted.
|
|
7041
7079
|
*/
|
|
7042
7080
|
async function runWidget(url, signerOrigin, ex, popupFallback) {
|
|
7043
|
-
if (!hasDOM$
|
|
7081
|
+
if (!hasDOM$3())
|
|
7044
7082
|
return popupFallback();
|
|
7045
7083
|
const m = getModal();
|
|
7046
7084
|
const requestId = String(ex.request.requestId);
|
|
@@ -7149,7 +7187,7 @@ async function runWidget(url, signerOrigin, ex, popupFallback) {
|
|
|
7149
7187
|
// ONE ORIGIN, ONE PASSKEY: a WebAuthn passkey is bound to a single origin, so ALL
|
|
7150
7188
|
// Bounded apps (any subdomain / custom domain) sign through this one origin - giving
|
|
7151
7189
|
// every user one wallet + one passkey that roams across every app.
|
|
7152
|
-
function hasDOM() {
|
|
7190
|
+
function hasDOM$1() {
|
|
7153
7191
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
7154
7192
|
}
|
|
7155
7193
|
// Safari (incl. iOS WebViews) is unreliable at running a WebAuthn CREATE inside a
|
|
@@ -7158,7 +7196,7 @@ function hasDOM() {
|
|
|
7158
7196
|
// There we pick the popup up front, from the original click, so enrollment is solid.
|
|
7159
7197
|
// Everywhere else the inline widget is used (buttery in-app modal).
|
|
7160
7198
|
function preferPopup() {
|
|
7161
|
-
if (!hasDOM() || typeof navigator === 'undefined')
|
|
7199
|
+
if (!hasDOM$1() || typeof navigator === 'undefined')
|
|
7162
7200
|
return true;
|
|
7163
7201
|
const ua = navigator.userAgent || '';
|
|
7164
7202
|
return /^((?!chrome|android|crios|fxios|edg|edga|opr).)*safari/i.test(ua);
|
|
@@ -7275,7 +7313,7 @@ async function runPopup(url, signerOrigin, ex) {
|
|
|
7275
7313
|
* Use this to learn the fee-payer address BEFORE building a transaction to sign.
|
|
7276
7314
|
*/
|
|
7277
7315
|
async function getOrCreateTurnkeyWallet() {
|
|
7278
|
-
if (!hasDOM())
|
|
7316
|
+
if (!hasDOM$1())
|
|
7279
7317
|
throw new Error('Turnkey embedded wallets are only available in the browser (popup-based).');
|
|
7280
7318
|
const { url, origin } = await turnkeySignerPage();
|
|
7281
7319
|
const requestId = `tkcreate_${Date.now()}_${++requestSeq}`;
|
|
@@ -7299,7 +7337,7 @@ async function getOrCreateTurnkeyWallet() {
|
|
|
7299
7337
|
* signatures are just a passkey approval.
|
|
7300
7338
|
*/
|
|
7301
7339
|
async function signSolanaMessageViaTurnkey(message) {
|
|
7302
|
-
if (!hasDOM()) {
|
|
7340
|
+
if (!hasDOM$1()) {
|
|
7303
7341
|
throw new Error('Turnkey embedded-wallet signing is only available in the browser (popup-based).');
|
|
7304
7342
|
}
|
|
7305
7343
|
const { url, origin } = await turnkeySignerPage();
|
|
@@ -7316,6 +7354,109 @@ async function signSolanaMessageViaTurnkey(message) {
|
|
|
7316
7354
|
});
|
|
7317
7355
|
}
|
|
7318
7356
|
|
|
7357
|
+
// bounded.onramp() - fund the signed-in user's wallet with Coinbase Onramp.
|
|
7358
|
+
//
|
|
7359
|
+
// Web-only. Opens Coinbase's hosted checkout (pay.coinbase.com) in a popup
|
|
7360
|
+
// (new-tab fallback) using a single-use session token minted by the Bounded
|
|
7361
|
+
// platform at POST <origin>/__bounded/onramp/session on the app's own origin.
|
|
7362
|
+
// The platform holds the Coinbase credential; the app never sees it. The
|
|
7363
|
+
// session is bound server-side to the caller's verified Bounded JWT, and the
|
|
7364
|
+
// destination defaults to that user's embedded wallet.
|
|
7365
|
+
//
|
|
7366
|
+
// Works on Bounded-served origins (<app>.bounded.page / custom domains). On a
|
|
7367
|
+
// local dev origin the session endpoint does not exist; we fail with a clear
|
|
7368
|
+
// error rather than guessing a host.
|
|
7369
|
+
function hasDOM() {
|
|
7370
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
7371
|
+
}
|
|
7372
|
+
/**
|
|
7373
|
+
* Open Coinbase Onramp for the signed-in user. Resolves when the popup closes.
|
|
7374
|
+
* Call from a click handler - popup blockers require user activation.
|
|
7375
|
+
*/
|
|
7376
|
+
async function onramp(options = {}) {
|
|
7377
|
+
var _a, _b, _c;
|
|
7378
|
+
if (!hasDOM())
|
|
7379
|
+
throw new Error('onramp() is web-only');
|
|
7380
|
+
const user = getCurrentUser();
|
|
7381
|
+
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;
|
|
7382
|
+
if (!address) {
|
|
7383
|
+
throw new Error(user
|
|
7384
|
+
? 'onramp(): the signed-in account has no wallet address - pass { address } explicitly'
|
|
7385
|
+
: 'onramp(): no signed-in user - call login() first or pass { address }');
|
|
7386
|
+
}
|
|
7387
|
+
const idToken = await getIdToken();
|
|
7388
|
+
if (!idToken)
|
|
7389
|
+
throw new Error('onramp(): no active session - call login() first');
|
|
7390
|
+
// Open the window synchronously so the click's user-activation window is not
|
|
7391
|
+
// consumed by the fetch below (same hard-won pattern as loginWithPopup).
|
|
7392
|
+
let popup = null;
|
|
7393
|
+
if (!options.newTab) {
|
|
7394
|
+
const w = options.width || 460;
|
|
7395
|
+
const h = options.height || 720;
|
|
7396
|
+
const left = window.screenX + (window.outerWidth - w) / 2;
|
|
7397
|
+
const top = window.screenY + (window.outerHeight - h) / 2;
|
|
7398
|
+
popup = window.open('', 'bounded-onramp', `width=${w},height=${h},left=${left},top=${top}`);
|
|
7399
|
+
}
|
|
7400
|
+
let session;
|
|
7401
|
+
try {
|
|
7402
|
+
const res = await fetch(`${window.location.origin}/__bounded/onramp/session`, {
|
|
7403
|
+
method: 'POST',
|
|
7404
|
+
headers: { Authorization: `Bearer ${idToken}`, 'content-type': 'application/json' },
|
|
7405
|
+
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 } : {}))),
|
|
7406
|
+
});
|
|
7407
|
+
if (!res.ok) {
|
|
7408
|
+
let detail = '';
|
|
7409
|
+
try {
|
|
7410
|
+
detail = (_c = (await res.json()).error) !== null && _c !== void 0 ? _c : '';
|
|
7411
|
+
}
|
|
7412
|
+
catch ( /* keep status only */_d) { /* keep status only */ }
|
|
7413
|
+
if (res.status === 404) {
|
|
7414
|
+
throw new Error('onramp(): session endpoint not found - onramp works on Bounded-served origins (your deployed app URL), not local dev servers');
|
|
7415
|
+
}
|
|
7416
|
+
throw new Error(`onramp(): session mint failed (${res.status}${detail ? `: ${detail}` : ''})`);
|
|
7417
|
+
}
|
|
7418
|
+
session = (await res.json());
|
|
7419
|
+
}
|
|
7420
|
+
catch (error) {
|
|
7421
|
+
try {
|
|
7422
|
+
popup === null || popup === void 0 ? void 0 : popup.close();
|
|
7423
|
+
}
|
|
7424
|
+
catch ( /* ignore */_e) { /* ignore */ }
|
|
7425
|
+
throw error;
|
|
7426
|
+
}
|
|
7427
|
+
if (popup) {
|
|
7428
|
+
try {
|
|
7429
|
+
popup.location.replace(session.url);
|
|
7430
|
+
}
|
|
7431
|
+
catch (_f) {
|
|
7432
|
+
try {
|
|
7433
|
+
popup.location.href = session.url;
|
|
7434
|
+
}
|
|
7435
|
+
catch (_g) {
|
|
7436
|
+
try {
|
|
7437
|
+
popup.close();
|
|
7438
|
+
}
|
|
7439
|
+
catch ( /* ignore */_h) { /* ignore */ }
|
|
7440
|
+
throw new Error('onramp(): popup failed to navigate - retry with { newTab: true }');
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
return await new Promise((resolve) => {
|
|
7444
|
+
const timer = setInterval(() => {
|
|
7445
|
+
if (popup.closed) {
|
|
7446
|
+
clearInterval(timer);
|
|
7447
|
+
resolve({ status: 'closed', address: session.address, asset: session.asset });
|
|
7448
|
+
}
|
|
7449
|
+
}, 500);
|
|
7450
|
+
});
|
|
7451
|
+
}
|
|
7452
|
+
// New-tab path (popup was blocked or explicitly requested): cross-origin tab
|
|
7453
|
+
// close is not observable, so resolve immediately.
|
|
7454
|
+
const tab = window.open(session.url, '_blank');
|
|
7455
|
+
if (!tab)
|
|
7456
|
+
throw new Error('onramp(): window.open was blocked - call onramp() from a click handler');
|
|
7457
|
+
return { status: 'opened', address: session.address, asset: session.asset };
|
|
7458
|
+
}
|
|
7459
|
+
|
|
7319
7460
|
/**
|
|
7320
7461
|
* Extracts a human-readable error message from Solana transaction logs.
|
|
7321
7462
|
*/
|
|
@@ -7445,7 +7586,7 @@ class PrivyExpoProvider {
|
|
|
7445
7586
|
return { provider: this, address: session.address };
|
|
7446
7587
|
}
|
|
7447
7588
|
// Stale session — clear and continue to fresh login flow
|
|
7448
|
-
getActiveSessionManager().clearSession();
|
|
7589
|
+
await getActiveSessionManager().clearSession();
|
|
7449
7590
|
}
|
|
7450
7591
|
// Trigger Privy login
|
|
7451
7592
|
const privyUser = await this.privyMethods.login();
|
|
@@ -7626,7 +7767,7 @@ class PrivyExpoProvider {
|
|
|
7626
7767
|
if ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.isAuthenticated) {
|
|
7627
7768
|
await this.privyMethods.logout();
|
|
7628
7769
|
}
|
|
7629
|
-
getActiveSessionManager().clearSession();
|
|
7770
|
+
await getActiveSessionManager().clearSession();
|
|
7630
7771
|
}
|
|
7631
7772
|
async getNativeMethods() {
|
|
7632
7773
|
return this.privyMethods;
|
|
@@ -7784,5 +7925,5 @@ function defaultInjectedEvmProvider() {
|
|
|
7784
7925
|
return null;
|
|
7785
7926
|
}
|
|
7786
7927
|
|
|
7787
|
-
export {
|
|
7788
|
-
//# sourceMappingURL=index-
|
|
7928
|
+
export { BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as $, completeLoginFromRedirect as A, loginWithPopup as B, completeLoginInPopup as C, openBoundedWidget as D, EMBEDDED_WALLET_UNSUPPORTED as E, useAuth as F, useQuery as G, useBuildRun as H, apps as I, deserializeTransaction as J, signSolanaMessageViaTurnkey as K, getOrCreateTurnkeyWallet as L, startTurnkeyEmailLogin as M, getIdToken as N, onramp as O, setPlatform as P, OffchainAuthProvider as Q, PrivyExpoProvider as R, requestEip6963Providers 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 _, hasEmbeddedEvmWallet as a, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as a0, embeddedSignAndSubmit as b, setAuthLoading as c, defaultInjectedProvider as d, embeddedRunEvmTransaction as e, bufferExports as f, getPlatform as g, hasEmbeddedWallet as h, bs58 as i, confirmAndCheckTransaction as j, defaultInjectedEvmProvider as k, init as l, getCurrentUser as m, normalizeSolanaRpcUrl as n, onAuthStateChanged as o, onAuthLoadingChanged as p, getAuthLoading as q, resolveSolanaRpcUrl as r, setCurrentUser as s, login as t, logout as u, getAuthProvider as v, signInAnonymously as w, loginWithPrivy as x, loginWithWallet as y, loginWithRedirect as z };
|
|
7929
|
+
//# sourceMappingURL=index-SHt4VZZV.mjs.map
|