@bounded-sh/client 0.0.112-ux-audit.2 → 0.0.113
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/bounded-widget-modal.d.ts +24 -2
- package/dist/auth/providers/injected-wallet-provider.d.ts +7 -0
- package/dist/auth/providers/injected-wallet-types.d.ts +2 -0
- package/dist/auth/providers/solana-mobile-registration.d.ts +18 -0
- package/dist/{email-auth-provider-BfCH7K6N.mjs → email-auth-provider-Bk5GSpYT.mjs} +2 -2
- package/dist/{email-auth-provider-C7RXLVd9.mjs.map → email-auth-provider-Bk5GSpYT.mjs.map} +1 -1
- package/dist/{email-auth-provider-DTrCfOJd.js → email-auth-provider-Cr66GaKw.js} +2 -2
- package/dist/{email-auth-provider-DTrCfOJd.js.map → email-auth-provider-Cr66GaKw.js.map} +1 -1
- package/dist/{email-auth-provider-53sA5_i2.js → email-auth-provider-DeORQbTK.js} +2 -2
- package/dist/{email-auth-provider-53sA5_i2.js.map → email-auth-provider-DeORQbTK.js.map} +1 -1
- package/dist/{email-auth-provider-C7RXLVd9.mjs → email-auth-provider-nDZjRDpj.mjs} +2 -2
- package/dist/{email-auth-provider-BfCH7K6N.mjs.map → email-auth-provider-nDZjRDpj.mjs.map} +1 -1
- package/dist/{guest-auth-provider-00KkSNpE.js → guest-auth-provider-5bX-xt6K.js} +2 -2
- package/dist/{guest-auth-provider-00KkSNpE.js.map → guest-auth-provider-5bX-xt6K.js.map} +1 -1
- package/dist/{guest-auth-provider-Tndt6tzJ.js → guest-auth-provider-CUNkZVFK.js} +2 -2
- package/dist/{guest-auth-provider-Tndt6tzJ.js.map → guest-auth-provider-CUNkZVFK.js.map} +1 -1
- package/dist/{guest-auth-provider-DjOFjtnk.mjs → guest-auth-provider-DDudqqxY.mjs} +2 -2
- package/dist/{guest-auth-provider-DjOFjtnk.mjs.map → guest-auth-provider-DDudqqxY.mjs.map} +1 -1
- package/dist/{guest-auth-provider-2J4fnTX5.mjs → guest-auth-provider-ejUTbjCC.mjs} +2 -2
- package/dist/{guest-auth-provider-2J4fnTX5.mjs.map → guest-auth-provider-ejUTbjCC.mjs.map} +1 -1
- package/dist/{index-D3kdhCpH.mjs → index-BAiLpNEQ.mjs} +190 -53
- package/dist/index-BAiLpNEQ.mjs.map +1 -0
- package/dist/{index-DJeEMevo.js → index-BZ0X1Z9X.js} +190 -53
- package/dist/index-BZ0X1Z9X.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{index.native-ingNhWPw.js → index.native-DJSOqyKQ.js} +101 -14
- package/dist/index.native-DJSOqyKQ.js.map +1 -0
- package/dist/{index.native-CAH_ks0s.mjs → index.native-DcW2klyn.mjs} +100 -15
- package/dist/index.native-DcW2klyn.mjs.map +1 -0
- package/dist/index.native.js +1 -1
- package/dist/index.native.mjs +1 -1
- package/dist/{injected-evm-wallet-provider-Cao1U0NZ.js → injected-evm-wallet-provider-BDYWjIOQ.js} +2 -2
- package/dist/{injected-evm-wallet-provider-Cao1U0NZ.js.map → injected-evm-wallet-provider-BDYWjIOQ.js.map} +1 -1
- package/dist/{injected-evm-wallet-provider-DXjwPjLW.mjs → injected-evm-wallet-provider-BQ_kG1vI.mjs} +2 -2
- package/dist/{injected-evm-wallet-provider-DXjwPjLW.mjs.map → injected-evm-wallet-provider-BQ_kG1vI.mjs.map} +1 -1
- package/dist/{injected-evm-wallet-provider-BtyG1HOX.mjs → injected-evm-wallet-provider-C4aKa2v1.mjs} +2 -2
- package/dist/{injected-evm-wallet-provider-BtyG1HOX.mjs.map → injected-evm-wallet-provider-C4aKa2v1.mjs.map} +1 -1
- package/dist/{injected-evm-wallet-provider-IlkuKffc.js → injected-evm-wallet-provider-D06arDQD.js} +2 -2
- package/dist/{injected-evm-wallet-provider-IlkuKffc.js.map → injected-evm-wallet-provider-D06arDQD.js.map} +1 -1
- package/dist/{injected-wallet-provider-BEYwsn6M.js → injected-wallet-provider-B9jvzDM5.js} +51 -22
- package/dist/{injected-wallet-provider-BEYwsn6M.js.map → injected-wallet-provider-B9jvzDM5.js.map} +1 -1
- package/dist/{injected-wallet-provider-0SSONh1d.mjs → injected-wallet-provider-Dj-F69gb.mjs} +51 -22
- package/dist/{injected-wallet-provider-0SSONh1d.mjs.map → injected-wallet-provider-Dj-F69gb.mjs.map} +1 -1
- package/dist/{injected-wallet-provider-DSlHfgMU.js → injected-wallet-provider-Dqmk-m4V.js} +67 -26
- package/dist/{injected-wallet-provider-DSlHfgMU.js.map → injected-wallet-provider-Dqmk-m4V.js.map} +1 -1
- package/dist/{injected-wallet-provider-CfYNIIHd.mjs → injected-wallet-provider-DxPcYxP-.mjs} +67 -26
- package/dist/{injected-wallet-provider-CfYNIIHd.mjs.map → injected-wallet-provider-DxPcYxP-.mjs.map} +1 -1
- package/package.json +2 -2
- package/dist/index-D3kdhCpH.mjs.map +0 -1
- package/dist/index-DJeEMevo.js.map +0 -1
- package/dist/index.native-CAH_ks0s.mjs.map +0 -1
- package/dist/index.native-ingNhWPw.js.map +0 -1
|
@@ -3796,6 +3796,46 @@ function looksLikeSolanaMobileWallet(name) {
|
|
|
3796
3796
|
function solanaMobileWalletLeavesPage(name) {
|
|
3797
3797
|
return name === LOCAL_MOBILE_WALLET_NAME;
|
|
3798
3798
|
}
|
|
3799
|
+
/**
|
|
3800
|
+
* Whether this wallet answers a sign-in from its authorization cache, so the
|
|
3801
|
+
* cached record must be dropped before asking it to sign in.
|
|
3802
|
+
*
|
|
3803
|
+
* Both Mobile Wallet Adapter transports consult their persisted authorization
|
|
3804
|
+
* before EVERY authorize call, including the one that carries the Sign In With
|
|
3805
|
+
* Solana payload (@solana-mobile/wallet-standard-mobile 0.5.3
|
|
3806
|
+
* lib/esm/index.browser.js:1291). A record left by a plain connect holds no
|
|
3807
|
+
* sign-in result, so that sign-in fails with "no sign in result returned by
|
|
3808
|
+
* wallet" without the wallet app ever being asked; a record left by an earlier
|
|
3809
|
+
* sign-in holds that OLD proof, so a later sign-in replays a spent nonce. The
|
|
3810
|
+
* wallet's own `standard:disconnect` clears the record locally - it opens
|
|
3811
|
+
* nothing - and the sign-in that follows then authorizes afresh, with its
|
|
3812
|
+
* payload, in the wallet app. A name check, like leavesPage: this describes the
|
|
3813
|
+
* transport, and the same adapter registered by another SDK behaves the same.
|
|
3814
|
+
*/
|
|
3815
|
+
function solanaMobileWalletAnswersSignInFromCache(name) {
|
|
3816
|
+
return mobileWalletNames.has(name);
|
|
3817
|
+
}
|
|
3818
|
+
/**
|
|
3819
|
+
* The Wallet Standard name of a feature a Mobile Wallet Adapter account reports.
|
|
3820
|
+
*
|
|
3821
|
+
* The adapter copies a wallet app's per-account `features` into the Wallet
|
|
3822
|
+
* Standard account untranslated (0.5.3 lib/esm/index.browser.js:1421), and the
|
|
3823
|
+
* MWA protocol names them differently from the Wallet Standard (spec feature
|
|
3824
|
+
* identifiers: `solana:signMessages`, `solana:signInWithSolana`,
|
|
3825
|
+
* `solana:signTransactions`). Filtered by the Wallet Standard names, such an
|
|
3826
|
+
* account looks unable to sign a message or sign in, and the page sees no
|
|
3827
|
+
* connected account after a successful authorization. Wallet Standard names pass
|
|
3828
|
+
* through unchanged, so this applies to every account.
|
|
3829
|
+
*/
|
|
3830
|
+
const MWA_FEATURE_NAMES = {
|
|
3831
|
+
'solana:signMessages': 'solana:signMessage',
|
|
3832
|
+
'solana:signInWithSolana': 'solana:signIn',
|
|
3833
|
+
'solana:signTransactions': 'solana:signTransaction',
|
|
3834
|
+
};
|
|
3835
|
+
function walletStandardFeatureName(feature) {
|
|
3836
|
+
var _a;
|
|
3837
|
+
return (_a = MWA_FEATURE_NAMES[feature]) !== null && _a !== void 0 ? _a : feature;
|
|
3838
|
+
}
|
|
3799
3839
|
/**
|
|
3800
3840
|
* Register Solana Mobile's MWA wallet with the Wallet Standard registry so
|
|
3801
3841
|
* wallet discovery surfaces it. Idempotent - the first wallet-lane activation
|
|
@@ -3876,9 +3916,13 @@ async function ensureSolanaMobileWalletRegistered(config, network) {
|
|
|
3876
3916
|
}
|
|
3877
3917
|
catch (_e) {
|
|
3878
3918
|
throw new WalletConfigError(`Bounded: Solana Mobile wallet support needs the optional peer dependency ` +
|
|
3879
|
-
`'@solana-mobile/wallet-standard-mobile', which is not installed.
|
|
3880
|
-
`
|
|
3881
|
-
`
|
|
3919
|
+
`'@solana-mobile/wallet-standard-mobile', which is not installed. Until it is, ` +
|
|
3920
|
+
`Android users (Seeker, Saga, any phone browser) get NO wallet to connect: ` +
|
|
3921
|
+
`installed wallet apps are never injected into a page there, the mobile adapter ` +
|
|
3922
|
+
`is the only route. Fix: npm install @solana-mobile/wallet-standard-mobile ` +
|
|
3923
|
+
`(a web app also needs legacy-peer-deps=true in its .npmrc, because the adapter's ` +
|
|
3924
|
+
`protocol package declares react-native as a peer). Or leave the Solana Mobile ` +
|
|
3925
|
+
`wallet out of this app's wallet configuration on purpose.`);
|
|
3882
3926
|
}
|
|
3883
3927
|
const { registerMwa, createDefaultChainSelector, SolanaMobileWalletAdapterWalletName, SolanaMobileWalletAdapterRemoteWalletName, } = mwa;
|
|
3884
3928
|
const before = new Set(getWallets().get());
|
|
@@ -3965,7 +4009,7 @@ const OVERLAY_CSS = `
|
|
|
3965
4009
|
:host{all:initial}
|
|
3966
4010
|
*{box-sizing:border-box}
|
|
3967
4011
|
.bw-ov{position:fixed;inset:0;z-index:2147483647;display:none;
|
|
3968
|
-
font-family:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif}
|
|
4012
|
+
font-family:"Bounded Schibsted Grotesk","Schibsted Grotesk","Helvetica Neue",Arial,sans-serif}
|
|
3969
4013
|
.bw-ov.mounted{display:block}
|
|
3970
4014
|
.bw-back{position:fixed;inset:0;background:rgba(4,4,5,.62);opacity:0;
|
|
3971
4015
|
transition:opacity .24s ease;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}
|
|
@@ -3998,6 +4042,29 @@ const OVERLAY_CSS = `
|
|
|
3998
4042
|
}
|
|
3999
4043
|
@media(prefers-reduced-motion:reduce){.bw-back,.bw-panel{transition:opacity .12s linear!important}}
|
|
4000
4044
|
`;
|
|
4045
|
+
/**
|
|
4046
|
+
* Style the shadow tree with `css` as constructed stylesheets, and say whether it could. A host
|
|
4047
|
+
* CSP whose style-src lacks 'unsafe-inline' refuses an inline <style> even inside a shadow root,
|
|
4048
|
+
* which left the widget unstyled (the Bounded router compiles exactly `style-src 'self'` for an
|
|
4049
|
+
* app that declares browser boundaries and names no style sources); CSP does not govern
|
|
4050
|
+
* constructed sheets. A browser without them (they shipped with adoptedStyleSheets everywhere)
|
|
4051
|
+
* gets <style> elements instead (styleTag).
|
|
4052
|
+
*/
|
|
4053
|
+
function adoptStyles(shadow, css) {
|
|
4054
|
+
if (!("adoptedStyleSheets" in shadow))
|
|
4055
|
+
return false;
|
|
4056
|
+
shadow.adoptedStyleSheets = css.map((text) => {
|
|
4057
|
+
const sheet = new CSSStyleSheet();
|
|
4058
|
+
sheet.replaceSync(text);
|
|
4059
|
+
return sheet;
|
|
4060
|
+
});
|
|
4061
|
+
return true;
|
|
4062
|
+
}
|
|
4063
|
+
function styleTag(css) {
|
|
4064
|
+
const style = document.createElement("style");
|
|
4065
|
+
style.textContent = css;
|
|
4066
|
+
return style;
|
|
4067
|
+
}
|
|
4001
4068
|
let modal = null;
|
|
4002
4069
|
function getModal() {
|
|
4003
4070
|
if (modal)
|
|
@@ -4005,9 +4072,8 @@ function getModal() {
|
|
|
4005
4072
|
const root = document.createElement("div");
|
|
4006
4073
|
root.setAttribute("data-bounded-widget", "");
|
|
4007
4074
|
const shadow = root.attachShadow({ mode: "open" });
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
shadow.appendChild(style);
|
|
4075
|
+
if (!adoptStyles(shadow, [OVERLAY_CSS]))
|
|
4076
|
+
shadow.appendChild(styleTag(OVERLAY_CSS));
|
|
4011
4077
|
const overlay = document.createElement("div");
|
|
4012
4078
|
overlay.className = "bw-ov";
|
|
4013
4079
|
const back = document.createElement("div");
|
|
@@ -4142,12 +4208,15 @@ function fitPanelToContent(m) {
|
|
|
4142
4208
|
m.fitObserver = ro;
|
|
4143
4209
|
}
|
|
4144
4210
|
}
|
|
4145
|
-
/** Switch the modal into NATIVE-content mode: detach any iframe, mount `node
|
|
4146
|
-
function mountContent(m, node) {
|
|
4211
|
+
/** Switch the modal into NATIVE-content mode: detach any iframe, mount `node`, styled by `css` until the next mount. */
|
|
4212
|
+
function mountContent(m, node, css) {
|
|
4147
4213
|
var _a;
|
|
4148
4214
|
detachIframe(m);
|
|
4149
4215
|
(_a = m.fitObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
4150
4216
|
m.fitObserver = null;
|
|
4217
|
+
const shadow = m.root.shadowRoot;
|
|
4218
|
+
if (!(shadow && adoptStyles(shadow, [OVERLAY_CSS, css] )) && css)
|
|
4219
|
+
node.prepend(styleTag(css));
|
|
4151
4220
|
m.content.replaceChildren(node);
|
|
4152
4221
|
m.content.style.display = "block";
|
|
4153
4222
|
}
|
|
@@ -4209,27 +4278,39 @@ function detachIframe(m) {
|
|
|
4209
4278
|
m.iframeContext = "";
|
|
4210
4279
|
m.onIframeMessage = null;
|
|
4211
4280
|
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4281
|
+
/**
|
|
4282
|
+
* The Bounded editorial typefaces the hosted auth page uses (Newsreader display, Schibsted
|
|
4283
|
+
* Grotesk body), registered once at the document level so they apply inside the shadow root.
|
|
4284
|
+
*
|
|
4285
|
+
* The Bounded router serves them same-origin at /__bounded/fonts/*.woff2 on every site it
|
|
4286
|
+
* serves (bounded-router scripts/build-widget-styles.cjs), and they load through the FontFace
|
|
4287
|
+
* API: no stylesheet, so a host CSP's style-src never applies, and the only fetch is same-origin,
|
|
4288
|
+
* which font-src 'self' admits. Google Fonts CSS injected here was refused by strict hosts such
|
|
4289
|
+
* as the OpenApps venue (style-src 'self'), with a CSP error on every page. A page the router
|
|
4290
|
+
* does not serve has none of its /__bounded/ scripts: nothing is fetched there, and the widget's
|
|
4291
|
+
* font stacks fall back to the page's own faces or system ones. The Bounded-prefixed family
|
|
4292
|
+
* names never restyle the host page's own text.
|
|
4293
|
+
*/
|
|
4294
|
+
const WIDGET_FONT_FACES = [
|
|
4295
|
+
{ family: "Bounded Newsreader", url: "/__bounded/fonts/newsreader.woff2", weight: "200 800" },
|
|
4296
|
+
{ family: "Bounded Schibsted Grotesk", url: "/__bounded/fonts/schibsted.woff2", weight: "400 900" },
|
|
4297
|
+
];
|
|
4216
4298
|
function ensureFonts() {
|
|
4217
|
-
if (!hasDOM$5())
|
|
4299
|
+
if (!hasDOM$5() || typeof FontFace === "undefined" || !document.fonts)
|
|
4218
4300
|
return;
|
|
4219
|
-
if (document.querySelector('
|
|
4301
|
+
if (!document.querySelector('script[src^="/__bounded/"]'))
|
|
4220
4302
|
return;
|
|
4221
|
-
const
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
document.head.append(pre1, pre2, link);
|
|
4303
|
+
const registered = new Set();
|
|
4304
|
+
document.fonts.forEach((face) => registered.add(face.family.replace(/^["']|["']$/g, "")));
|
|
4305
|
+
for (const { family, url, weight } of WIDGET_FONT_FACES) {
|
|
4306
|
+
if (registered.has(family))
|
|
4307
|
+
continue;
|
|
4308
|
+
// Against the page's origin, not its base URL: a <base href> elsewhere must not move the fetch off this origin.
|
|
4309
|
+
const face = new FontFace(family, `url("${location.origin}${url}") format("woff2")`, { weight, display: "swap" });
|
|
4310
|
+
document.fonts.add(face);
|
|
4311
|
+
// A face that cannot load is taken back out; the font stack falls back to the next face.
|
|
4312
|
+
face.load().catch(() => { document.fonts.delete(face); });
|
|
4313
|
+
}
|
|
4233
4314
|
}
|
|
4234
4315
|
|
|
4235
4316
|
// turnkey-wallet-widget.ts - runs one Turnkey signer exchange inside the shared
|
|
@@ -6249,7 +6330,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6249
6330
|
// manager as legacy email sessions. Human login should be started
|
|
6250
6331
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
6251
6332
|
// logout surface for those sessions.
|
|
6252
|
-
currentAuthProvider = new (await import('./email-auth-provider-
|
|
6333
|
+
currentAuthProvider = new (await import('./email-auth-provider-nDZjRDpj.mjs')).EmailAuthProvider();
|
|
6253
6334
|
break;
|
|
6254
6335
|
case "phantom": {
|
|
6255
6336
|
// First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
|
|
@@ -6291,7 +6372,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6291
6372
|
// (bounded-login-widget.ts), so registration never counts as
|
|
6292
6373
|
// evidence the user has a wallet.
|
|
6293
6374
|
await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
|
|
6294
|
-
const { InjectedWalletProvider } = await import('./injected-wallet-provider-
|
|
6375
|
+
const { InjectedWalletProvider } = await import('./injected-wallet-provider-Dj-F69gb.mjs');
|
|
6295
6376
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
6296
6377
|
break;
|
|
6297
6378
|
}
|
|
@@ -6304,7 +6385,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6304
6385
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
6305
6386
|
// to point at a specific wallet or set chainId/domain.
|
|
6306
6387
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
6307
|
-
const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-
|
|
6388
|
+
const { InjectedEvmWalletProvider } = await import('./injected-evm-wallet-provider-C4aKa2v1.mjs');
|
|
6308
6389
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
6309
6390
|
break;
|
|
6310
6391
|
}
|
|
@@ -6329,7 +6410,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6329
6410
|
break;
|
|
6330
6411
|
case "guest":
|
|
6331
6412
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
6332
|
-
currentAuthProvider = new (await import('./guest-auth-provider-
|
|
6413
|
+
currentAuthProvider = new (await import('./guest-auth-provider-ejUTbjCC.mjs')).GuestAuthProvider();
|
|
6333
6414
|
break;
|
|
6334
6415
|
}
|
|
6335
6416
|
if (!currentAuthProvider) {
|
|
@@ -6391,7 +6472,7 @@ async function signInAnonymously() {
|
|
|
6391
6472
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
6392
6473
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
6393
6474
|
// so bundle-splitting can see it.
|
|
6394
|
-
const provider = new (await import('./guest-auth-provider-
|
|
6475
|
+
const provider = new (await import('./guest-auth-provider-ejUTbjCC.mjs')).GuestAuthProvider();
|
|
6395
6476
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
6396
6477
|
// adoptSessionProvider awaits only getConfig() (already resolved here) and then
|
|
6397
6478
|
// runs every write - provider/method/config/marker/user - in one synchronous
|
|
@@ -6562,7 +6643,7 @@ function ensureSharedWalletLoginReady() {
|
|
|
6562
6643
|
if (!sharedWalletReady) {
|
|
6563
6644
|
sharedWalletReady = (async () => {
|
|
6564
6645
|
await getConfig();
|
|
6565
|
-
await import('./injected-wallet-provider-
|
|
6646
|
+
await import('./injected-wallet-provider-Dj-F69gb.mjs');
|
|
6566
6647
|
})().catch((error) => {
|
|
6567
6648
|
sharedWalletReady = null;
|
|
6568
6649
|
throw error;
|
|
@@ -6665,7 +6746,7 @@ async function loginWithWallet(options) {
|
|
|
6665
6746
|
await ensureSharedWalletLoginReady();
|
|
6666
6747
|
else
|
|
6667
6748
|
await ensureWalletLoginReady();
|
|
6668
|
-
const { InjectedWalletProvider } = await import('./injected-wallet-provider-
|
|
6749
|
+
const { InjectedWalletProvider } = await import('./injected-wallet-provider-Dj-F69gb.mjs');
|
|
6669
6750
|
// Keep the RAW wallet provider: the offchain wrapper forwards only a fixed
|
|
6670
6751
|
// set of methods, so cleanup below must speak to the provider that actually
|
|
6671
6752
|
// holds the config rather than to whatever is wrapping it.
|
|
@@ -7032,6 +7113,13 @@ function registerStorageBridge() {
|
|
|
7032
7113
|
void syncStoredSession().catch((error) => console.warn('Bounded session synchronization failed:', error));
|
|
7033
7114
|
});
|
|
7034
7115
|
}
|
|
7116
|
+
function sameSessionIdentity(next, previous) {
|
|
7117
|
+
if (!next || !previous)
|
|
7118
|
+
return false;
|
|
7119
|
+
const a = deriveUserIdentityFromIdToken(next);
|
|
7120
|
+
const b = deriveUserIdentityFromIdToken(previous);
|
|
7121
|
+
return !!a.id && a.id === b.id && a.address === b.address && a.email === b.email && a.evmAddress === b.evmAddress;
|
|
7122
|
+
}
|
|
7035
7123
|
async function syncStoredSession() {
|
|
7036
7124
|
const config = initializedConfig;
|
|
7037
7125
|
if (!config)
|
|
@@ -7040,6 +7128,18 @@ async function syncStoredSession() {
|
|
|
7040
7128
|
const issuer = WebSessionManager.getIssuer();
|
|
7041
7129
|
if (token === observedIdToken && issuer === observedIssuer)
|
|
7042
7130
|
return;
|
|
7131
|
+
// Another tab refreshed this same session (tokens rotate every few minutes):
|
|
7132
|
+
// who is signed in did not change, so keep the user and its live reads, whose
|
|
7133
|
+
// sockets take the new token on their own, instead of hiding and restoring it.
|
|
7134
|
+
if (currentUser && issuer === observedIssuer && sameSessionIdentity(token, observedIdToken)) {
|
|
7135
|
+
const record = await WebSessionManager.readSessionWithGeneration();
|
|
7136
|
+
if (config !== initializedConfig || WebSessionManager.getIdToken() !== token)
|
|
7137
|
+
return;
|
|
7138
|
+
if ((record === null || record === void 0 ? void 0 : record.idToken) === token && (!record.appId || record.appId === config.appId)) {
|
|
7139
|
+
observedIdToken = token;
|
|
7140
|
+
return;
|
|
7141
|
+
}
|
|
7142
|
+
}
|
|
7043
7143
|
observedIdToken = token;
|
|
7044
7144
|
observedIssuer = issuer;
|
|
7045
7145
|
const generation = ++initializationGeneration;
|
|
@@ -7536,7 +7636,9 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
|
|
|
7536
7636
|
// mobile adapter fills DEFAULT_FEATURES in exactly that case. So an empty list
|
|
7537
7637
|
// means none, and reading it as "everything" picks an account that cannot sign
|
|
7538
7638
|
// and fails at the wallet instead of here.
|
|
7539
|
-
|
|
7639
|
+
// The mobile adapter hands a wallet app's own feature names through
|
|
7640
|
+
// untranslated, so each name is read as its Wallet Standard equivalent.
|
|
7641
|
+
const accountSupports = (account, feature) => account.features.some((f) => walletStandardFeatureName(f) === feature);
|
|
7540
7642
|
const pickSolanaAccount = (accounts) => {
|
|
7541
7643
|
// With a network configured, an account that does not support it is not a
|
|
7542
7644
|
// usable account: `WalletAccount.chains` is what that account can sign for,
|
|
@@ -7611,13 +7713,23 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
|
|
|
7611
7713
|
} }, (hasFeature(wallet, SolanaSignIn)
|
|
7612
7714
|
? {
|
|
7613
7715
|
async signIn(input) {
|
|
7614
|
-
|
|
7615
|
-
if (!accountSupports(acc, SolanaSignIn))
|
|
7616
|
-
throw new Error("Wallet account does not support solana:signIn");
|
|
7716
|
+
var _a;
|
|
7617
7717
|
const sign = feature(wallet, SolanaSignIn);
|
|
7618
7718
|
if (!sign)
|
|
7619
7719
|
throw new Error("Wallet does not support solana:signIn");
|
|
7720
|
+
const open = currentAccount();
|
|
7721
|
+
if (open && !accountSupports(open, SolanaSignIn))
|
|
7722
|
+
throw new Error("Wallet account does not support solana:signIn");
|
|
7723
|
+
if (solanaMobileWalletAnswersSignInFromCache(wallet.name)) {
|
|
7724
|
+
// Drop the cached authorization so this sign-in is performed by the
|
|
7725
|
+
// wallet app, with its payload, rather than answered from a record
|
|
7726
|
+
// that holds no sign-in result or an earlier sign-in's spent nonce.
|
|
7727
|
+
// Local to the page: the adapter's disconnect opens nothing.
|
|
7728
|
+
await ((_a = feature(wallet, StandardDisconnect)) === null || _a === void 0 ? void 0 : _a.disconnect());
|
|
7729
|
+
}
|
|
7620
7730
|
const [out] = await sign.signIn(input);
|
|
7731
|
+
if (!out)
|
|
7732
|
+
throw new Error("Wallet returned no sign-in result");
|
|
7621
7733
|
return { account: { address: out.account.address }, signedMessage: out.signedMessage, signature: out.signature };
|
|
7622
7734
|
},
|
|
7623
7735
|
}
|
|
@@ -8067,8 +8179,8 @@ const CARD_CSS = `
|
|
|
8067
8179
|
--line:rgba(232,230,222,.08);--line-strong:rgba(232,230,222,.16);
|
|
8068
8180
|
--text:#e8e6de;--dim:#9b9991;--faint:#85837c;
|
|
8069
8181
|
--green:#58c98f;--green-bg:rgba(88,201,143,.09);--green-line:rgba(88,201,143,.28);--red:#ec8488;
|
|
8070
|
-
--disp:"Newsreader","Iowan Old Style",Georgia,serif;
|
|
8071
|
-
--body:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
|
|
8182
|
+
--disp:"Bounded Newsreader","Newsreader","Iowan Old Style",Georgia,serif;
|
|
8183
|
+
--body:"Bounded Schibsted Grotesk","Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
|
|
8072
8184
|
position:relative;padding:34px 32px 20px;color:var(--text);font-family:var(--body);
|
|
8073
8185
|
-webkit-font-smoothing:antialiased}
|
|
8074
8186
|
.x{position:absolute;top:20px;right:24px;border:0;background:transparent;color:var(--faint);
|
|
@@ -8189,6 +8301,17 @@ function discoverWallets(configuredNetwork) {
|
|
|
8189
8301
|
// beats a click that does nothing, which is what "one at a time" looks like from
|
|
8190
8302
|
// the outside.
|
|
8191
8303
|
const BUSY_MSG = "A sign-in is already in progress - finish or cancel it first.";
|
|
8304
|
+
// Shown instead of an empty card when no lane can be offered (wallet-only app,
|
|
8305
|
+
// no wallet in this browser). A phone browser never sees installed wallet apps
|
|
8306
|
+
// as injected providers, so the honest advice there is a different browser,
|
|
8307
|
+
// not "install a wallet".
|
|
8308
|
+
function noLaneCopy(mobile) {
|
|
8309
|
+
return mobile
|
|
8310
|
+
? "No wallet is available in this browser. Open this page in your wallet app's " +
|
|
8311
|
+
"browser, or on a desktop browser with a wallet extension, then try again."
|
|
8312
|
+
: "No wallet was found in this browser. Install a Solana wallet extension such as " +
|
|
8313
|
+
"Phantom or Solflare, reload the page, then try again.";
|
|
8314
|
+
}
|
|
8192
8315
|
const METHOD_LABEL = {
|
|
8193
8316
|
google: "Continue with Google",
|
|
8194
8317
|
apple: "Continue with Apple",
|
|
@@ -8530,12 +8653,9 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8530
8653
|
cancelPendingOpens();
|
|
8531
8654
|
};
|
|
8532
8655
|
m.onBackdrop = cancel;
|
|
8533
|
-
const style = el("style");
|
|
8534
|
-
style.textContent = CARD_CSS;
|
|
8535
8656
|
let emailDraft = "";
|
|
8536
8657
|
const renderChoose = (initialError) => {
|
|
8537
8658
|
const card = el("div", "c");
|
|
8538
|
-
card.appendChild(style.cloneNode(true));
|
|
8539
8659
|
const x = el("button", "x", "Close");
|
|
8540
8660
|
x.type = "button";
|
|
8541
8661
|
x.setAttribute("aria-label", "Close");
|
|
@@ -8752,6 +8872,24 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8752
8872
|
});
|
|
8753
8873
|
};
|
|
8754
8874
|
}
|
|
8875
|
+
// A card with no lane at all. It happens when an app asks for wallet-only
|
|
8876
|
+
// (`methods: []`, `wallet: true`) and this browser has no wallet to offer:
|
|
8877
|
+
// no injected wallet, and no Solana Mobile wallet (off-Android, or the app
|
|
8878
|
+
// never installed the adapter). A blank card between the title and the
|
|
8879
|
+
// footer was the shipped behaviour, and it reads as "the site is broken"
|
|
8880
|
+
// to the person and tells the developer nothing. Say what is missing on
|
|
8881
|
+
// screen, and name the usual cause once in the console, where the
|
|
8882
|
+
// developer's own preview run will show it.
|
|
8883
|
+
if (!hasEmail && social.length === 0 && !walletEnabled) {
|
|
8884
|
+
card.appendChild(el("p", "sub", noLaneCopy(detectMobile())));
|
|
8885
|
+
console.warn("[Bounded] openBoundedWidget has no sign-in lane to show: the app asked for " +
|
|
8886
|
+
"no email or social method and no wallet is available in this browser. " +
|
|
8887
|
+
(offerMobile
|
|
8888
|
+
? "On Android the Solana Mobile wallet is offered only when the app installs " +
|
|
8889
|
+
"'@solana-mobile/wallet-standard-mobile' (see the warning above if registration failed); "
|
|
8890
|
+
: "") +
|
|
8891
|
+
"Add a method, or make sure wallet login is enabled and the mobile adapter is installed.");
|
|
8892
|
+
}
|
|
8755
8893
|
card.appendChild(status);
|
|
8756
8894
|
const foot = el("div", "foot");
|
|
8757
8895
|
const poweredBy = el("a", undefined, "Powered by Bounded");
|
|
@@ -8762,11 +8900,13 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8762
8900
|
card.appendChild(foot);
|
|
8763
8901
|
return card;
|
|
8764
8902
|
};
|
|
8765
|
-
// Solana Mobile leaves the page to sign:
|
|
8766
|
-
// started login, so requesting the
|
|
8767
|
-
// no transient activation left,
|
|
8768
|
-
//
|
|
8769
|
-
//
|
|
8903
|
+
// Solana Mobile leaves the page to sign in: the nonce fetch that precedes
|
|
8904
|
+
// the sign-in outlives the tap that started login, so requesting the
|
|
8905
|
+
// sign-in straight afterwards runs with no transient activation left,
|
|
8906
|
+
// Chrome blocks the `solana-wallet:` intent navigation, and the protocol
|
|
8907
|
+
// reports the wallet as missing. Collect a fresh tap on its OWN view (one
|
|
8908
|
+
// wallet trip: sign-in authorizes and signs in the same step, there is no
|
|
8909
|
+
// connect before it) - never by adding a listener to a button that
|
|
8770
8910
|
// already starts a login, which would run both handlers on that tap and
|
|
8771
8911
|
// kick off a duplicate login beside the one waiting for the gesture.
|
|
8772
8912
|
// Injected wallets sign in-page and get no extra step.
|
|
@@ -8798,7 +8938,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8798
8938
|
const renderSignInGesture = (choice, done) => {
|
|
8799
8939
|
var _a;
|
|
8800
8940
|
const card = el("div", "c");
|
|
8801
|
-
card.appendChild(style.cloneNode(true));
|
|
8802
8941
|
const x = el("button", "x", "Close");
|
|
8803
8942
|
x.type = "button";
|
|
8804
8943
|
x.setAttribute("aria-label", "Close");
|
|
@@ -8819,7 +8958,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8819
8958
|
};
|
|
8820
8959
|
const renderWallets = (initialError) => {
|
|
8821
8960
|
const card = el("div", "c");
|
|
8822
|
-
card.appendChild(style.cloneNode(true));
|
|
8823
8961
|
const back = el("button", "back", "\u2190 Back");
|
|
8824
8962
|
back.type = "button";
|
|
8825
8963
|
// Leaving the wallet list supersedes any attempt still preparing, so it
|
|
@@ -8899,7 +9037,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8899
9037
|
// experience still feels native; the code input, sealing, and verify all live behind the frame.
|
|
8900
9038
|
const renderOtpFrame = (handle) => {
|
|
8901
9039
|
const card = el("div", "c");
|
|
8902
|
-
card.appendChild(style.cloneNode(true));
|
|
8903
9040
|
const back = el("button", "back", "\u2190 Back");
|
|
8904
9041
|
back.type = "button";
|
|
8905
9042
|
card.appendChild(back);
|
|
@@ -8946,7 +9083,7 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8946
9083
|
// land after a newer open has taken over the DOM.
|
|
8947
9084
|
if (!owner.owns())
|
|
8948
9085
|
return;
|
|
8949
|
-
mountContent(m, node);
|
|
9086
|
+
mountContent(m, node, CARD_CSS);
|
|
8950
9087
|
requestAnimationFrame(() => {
|
|
8951
9088
|
if (owner.owns())
|
|
8952
9089
|
fitPanelToContent(m);
|
|
@@ -11268,4 +11405,4 @@ function init(config = {}) {
|
|
|
11268
11405
|
}
|
|
11269
11406
|
|
|
11270
11407
|
export { onrampStatus as $, getAuthProvider as A, signInAnonymously as B, loginWithPrivy as C, loginWithWallet as D, ensureWalletLoginReady as E, ensureSharedWalletLoginReady as F, preloadWalletLogin as G, loginWithRedirect as H, completeLoginFromRedirect as I, getLoginReturnError as J, loginWithPopup as K, openBoundedWidget as L, ensureSignedIn as M, useAuth as N, useQuery as O, useBuildRun as P, apps as Q, signSolanaMessageViaTurnkey as R, getOrCreateTurnkeyWallet as S, openTurnkeyKeyExport as T, getTurnkeyWalletSessionState as U, getTurnkeyWalletRecoveryUrl as V, WalletConfigError as W, startTurnkeyEmailLogin as X, getIdToken as Y, onramp as Z, onrampQuote as _, signMessageWithTurnkey as a, setPlatform as a0, OffchainAuthProvider as a1, PrivyExpoProvider as a2, requestEip6963Providers as a3, connectBroadcast as a4, connectServiceSession as a5, builds as a6, BuildsApiError as a7, mediaAgentTools as a8, NON_TERMINAL_STATES as a9, TERMINAL_STATES as aa, RUN_STATES as ab, PARK_REASONS as ac, FAILURE_REASONS as ad, BUILD_REVIEW_CAPABILITY_SCHEMA as ae, BUILD_REVIEW_CAPABILITY_REFRESH_SCHEMA as af, BUILD_DELEGATED_REVIEW_CAPABILITY_SCHEMA as ag, signTransactionWithTurnkey as b, signTransactionV1WithTurnkey as c, signAndSubmitTransactionWithTurnkey as d, bs58 as e, defaultInjectedProvider as f, getPlatform as g, hasTurnkeyWallet as h, firstStandardWalletProvider as i, setAuthLoading as j, bufferExports as k, setStoredAuthMethod as l, confirmAndCheckTransaction as m, normalizeSolanaRpcUrl as n, defaultInjectedEvmProvider as o, init as p, getCurrentUser as q, resolveSolanaRpcUrl as r, setCurrentUser as s, transactionHasSignature as t, onAuthStateChanged as u, onAuthLoadingChanged as v, getAuthLoading as w, waitForAuthReady as x, login as y, logout as z };
|
|
11271
|
-
//# sourceMappingURL=index-
|
|
11408
|
+
//# sourceMappingURL=index-BAiLpNEQ.mjs.map
|