@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
|
@@ -3817,6 +3817,46 @@ function looksLikeSolanaMobileWallet(name) {
|
|
|
3817
3817
|
function solanaMobileWalletLeavesPage(name) {
|
|
3818
3818
|
return name === LOCAL_MOBILE_WALLET_NAME;
|
|
3819
3819
|
}
|
|
3820
|
+
/**
|
|
3821
|
+
* Whether this wallet answers a sign-in from its authorization cache, so the
|
|
3822
|
+
* cached record must be dropped before asking it to sign in.
|
|
3823
|
+
*
|
|
3824
|
+
* Both Mobile Wallet Adapter transports consult their persisted authorization
|
|
3825
|
+
* before EVERY authorize call, including the one that carries the Sign In With
|
|
3826
|
+
* Solana payload (@solana-mobile/wallet-standard-mobile 0.5.3
|
|
3827
|
+
* lib/esm/index.browser.js:1291). A record left by a plain connect holds no
|
|
3828
|
+
* sign-in result, so that sign-in fails with "no sign in result returned by
|
|
3829
|
+
* wallet" without the wallet app ever being asked; a record left by an earlier
|
|
3830
|
+
* sign-in holds that OLD proof, so a later sign-in replays a spent nonce. The
|
|
3831
|
+
* wallet's own `standard:disconnect` clears the record locally - it opens
|
|
3832
|
+
* nothing - and the sign-in that follows then authorizes afresh, with its
|
|
3833
|
+
* payload, in the wallet app. A name check, like leavesPage: this describes the
|
|
3834
|
+
* transport, and the same adapter registered by another SDK behaves the same.
|
|
3835
|
+
*/
|
|
3836
|
+
function solanaMobileWalletAnswersSignInFromCache(name) {
|
|
3837
|
+
return mobileWalletNames.has(name);
|
|
3838
|
+
}
|
|
3839
|
+
/**
|
|
3840
|
+
* The Wallet Standard name of a feature a Mobile Wallet Adapter account reports.
|
|
3841
|
+
*
|
|
3842
|
+
* The adapter copies a wallet app's per-account `features` into the Wallet
|
|
3843
|
+
* Standard account untranslated (0.5.3 lib/esm/index.browser.js:1421), and the
|
|
3844
|
+
* MWA protocol names them differently from the Wallet Standard (spec feature
|
|
3845
|
+
* identifiers: `solana:signMessages`, `solana:signInWithSolana`,
|
|
3846
|
+
* `solana:signTransactions`). Filtered by the Wallet Standard names, such an
|
|
3847
|
+
* account looks unable to sign a message or sign in, and the page sees no
|
|
3848
|
+
* connected account after a successful authorization. Wallet Standard names pass
|
|
3849
|
+
* through unchanged, so this applies to every account.
|
|
3850
|
+
*/
|
|
3851
|
+
const MWA_FEATURE_NAMES = {
|
|
3852
|
+
'solana:signMessages': 'solana:signMessage',
|
|
3853
|
+
'solana:signInWithSolana': 'solana:signIn',
|
|
3854
|
+
'solana:signTransactions': 'solana:signTransaction',
|
|
3855
|
+
};
|
|
3856
|
+
function walletStandardFeatureName(feature) {
|
|
3857
|
+
var _a;
|
|
3858
|
+
return (_a = MWA_FEATURE_NAMES[feature]) !== null && _a !== void 0 ? _a : feature;
|
|
3859
|
+
}
|
|
3820
3860
|
/**
|
|
3821
3861
|
* Register Solana Mobile's MWA wallet with the Wallet Standard registry so
|
|
3822
3862
|
* wallet discovery surfaces it. Idempotent - the first wallet-lane activation
|
|
@@ -3897,9 +3937,13 @@ async function ensureSolanaMobileWalletRegistered(config, network) {
|
|
|
3897
3937
|
}
|
|
3898
3938
|
catch (_e) {
|
|
3899
3939
|
throw new WalletConfigError(`Bounded: Solana Mobile wallet support needs the optional peer dependency ` +
|
|
3900
|
-
`'@solana-mobile/wallet-standard-mobile', which is not installed.
|
|
3901
|
-
`
|
|
3902
|
-
`
|
|
3940
|
+
`'@solana-mobile/wallet-standard-mobile', which is not installed. Until it is, ` +
|
|
3941
|
+
`Android users (Seeker, Saga, any phone browser) get NO wallet to connect: ` +
|
|
3942
|
+
`installed wallet apps are never injected into a page there, the mobile adapter ` +
|
|
3943
|
+
`is the only route. Fix: npm install @solana-mobile/wallet-standard-mobile ` +
|
|
3944
|
+
`(a web app also needs legacy-peer-deps=true in its .npmrc, because the adapter's ` +
|
|
3945
|
+
`protocol package declares react-native as a peer). Or leave the Solana Mobile ` +
|
|
3946
|
+
`wallet out of this app's wallet configuration on purpose.`);
|
|
3903
3947
|
}
|
|
3904
3948
|
const { registerMwa, createDefaultChainSelector, SolanaMobileWalletAdapterWalletName, SolanaMobileWalletAdapterRemoteWalletName, } = mwa;
|
|
3905
3949
|
const before = new Set(getWallets().get());
|
|
@@ -3986,7 +4030,7 @@ const OVERLAY_CSS = `
|
|
|
3986
4030
|
:host{all:initial}
|
|
3987
4031
|
*{box-sizing:border-box}
|
|
3988
4032
|
.bw-ov{position:fixed;inset:0;z-index:2147483647;display:none;
|
|
3989
|
-
font-family:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif}
|
|
4033
|
+
font-family:"Bounded Schibsted Grotesk","Schibsted Grotesk","Helvetica Neue",Arial,sans-serif}
|
|
3990
4034
|
.bw-ov.mounted{display:block}
|
|
3991
4035
|
.bw-back{position:fixed;inset:0;background:rgba(4,4,5,.62);opacity:0;
|
|
3992
4036
|
transition:opacity .24s ease;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}
|
|
@@ -4019,6 +4063,29 @@ const OVERLAY_CSS = `
|
|
|
4019
4063
|
}
|
|
4020
4064
|
@media(prefers-reduced-motion:reduce){.bw-back,.bw-panel{transition:opacity .12s linear!important}}
|
|
4021
4065
|
`;
|
|
4066
|
+
/**
|
|
4067
|
+
* Style the shadow tree with `css` as constructed stylesheets, and say whether it could. A host
|
|
4068
|
+
* CSP whose style-src lacks 'unsafe-inline' refuses an inline <style> even inside a shadow root,
|
|
4069
|
+
* which left the widget unstyled (the Bounded router compiles exactly `style-src 'self'` for an
|
|
4070
|
+
* app that declares browser boundaries and names no style sources); CSP does not govern
|
|
4071
|
+
* constructed sheets. A browser without them (they shipped with adoptedStyleSheets everywhere)
|
|
4072
|
+
* gets <style> elements instead (styleTag).
|
|
4073
|
+
*/
|
|
4074
|
+
function adoptStyles(shadow, css) {
|
|
4075
|
+
if (!("adoptedStyleSheets" in shadow))
|
|
4076
|
+
return false;
|
|
4077
|
+
shadow.adoptedStyleSheets = css.map((text) => {
|
|
4078
|
+
const sheet = new CSSStyleSheet();
|
|
4079
|
+
sheet.replaceSync(text);
|
|
4080
|
+
return sheet;
|
|
4081
|
+
});
|
|
4082
|
+
return true;
|
|
4083
|
+
}
|
|
4084
|
+
function styleTag(css) {
|
|
4085
|
+
const style = document.createElement("style");
|
|
4086
|
+
style.textContent = css;
|
|
4087
|
+
return style;
|
|
4088
|
+
}
|
|
4022
4089
|
let modal = null;
|
|
4023
4090
|
function getModal() {
|
|
4024
4091
|
if (modal)
|
|
@@ -4026,9 +4093,8 @@ function getModal() {
|
|
|
4026
4093
|
const root = document.createElement("div");
|
|
4027
4094
|
root.setAttribute("data-bounded-widget", "");
|
|
4028
4095
|
const shadow = root.attachShadow({ mode: "open" });
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
shadow.appendChild(style);
|
|
4096
|
+
if (!adoptStyles(shadow, [OVERLAY_CSS]))
|
|
4097
|
+
shadow.appendChild(styleTag(OVERLAY_CSS));
|
|
4032
4098
|
const overlay = document.createElement("div");
|
|
4033
4099
|
overlay.className = "bw-ov";
|
|
4034
4100
|
const back = document.createElement("div");
|
|
@@ -4163,12 +4229,15 @@ function fitPanelToContent(m) {
|
|
|
4163
4229
|
m.fitObserver = ro;
|
|
4164
4230
|
}
|
|
4165
4231
|
}
|
|
4166
|
-
/** Switch the modal into NATIVE-content mode: detach any iframe, mount `node
|
|
4167
|
-
function mountContent(m, node) {
|
|
4232
|
+
/** Switch the modal into NATIVE-content mode: detach any iframe, mount `node`, styled by `css` until the next mount. */
|
|
4233
|
+
function mountContent(m, node, css) {
|
|
4168
4234
|
var _a;
|
|
4169
4235
|
detachIframe(m);
|
|
4170
4236
|
(_a = m.fitObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
4171
4237
|
m.fitObserver = null;
|
|
4238
|
+
const shadow = m.root.shadowRoot;
|
|
4239
|
+
if (!(shadow && adoptStyles(shadow, [OVERLAY_CSS, css] )) && css)
|
|
4240
|
+
node.prepend(styleTag(css));
|
|
4172
4241
|
m.content.replaceChildren(node);
|
|
4173
4242
|
m.content.style.display = "block";
|
|
4174
4243
|
}
|
|
@@ -4230,27 +4299,39 @@ function detachIframe(m) {
|
|
|
4230
4299
|
m.iframeContext = "";
|
|
4231
4300
|
m.onIframeMessage = null;
|
|
4232
4301
|
}
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4302
|
+
/**
|
|
4303
|
+
* The Bounded editorial typefaces the hosted auth page uses (Newsreader display, Schibsted
|
|
4304
|
+
* Grotesk body), registered once at the document level so they apply inside the shadow root.
|
|
4305
|
+
*
|
|
4306
|
+
* The Bounded router serves them same-origin at /__bounded/fonts/*.woff2 on every site it
|
|
4307
|
+
* serves (bounded-router scripts/build-widget-styles.cjs), and they load through the FontFace
|
|
4308
|
+
* API: no stylesheet, so a host CSP's style-src never applies, and the only fetch is same-origin,
|
|
4309
|
+
* which font-src 'self' admits. Google Fonts CSS injected here was refused by strict hosts such
|
|
4310
|
+
* as the OpenApps venue (style-src 'self'), with a CSP error on every page. A page the router
|
|
4311
|
+
* does not serve has none of its /__bounded/ scripts: nothing is fetched there, and the widget's
|
|
4312
|
+
* font stacks fall back to the page's own faces or system ones. The Bounded-prefixed family
|
|
4313
|
+
* names never restyle the host page's own text.
|
|
4314
|
+
*/
|
|
4315
|
+
const WIDGET_FONT_FACES = [
|
|
4316
|
+
{ family: "Bounded Newsreader", url: "/__bounded/fonts/newsreader.woff2", weight: "200 800" },
|
|
4317
|
+
{ family: "Bounded Schibsted Grotesk", url: "/__bounded/fonts/schibsted.woff2", weight: "400 900" },
|
|
4318
|
+
];
|
|
4237
4319
|
function ensureFonts() {
|
|
4238
|
-
if (!hasDOM$5())
|
|
4320
|
+
if (!hasDOM$5() || typeof FontFace === "undefined" || !document.fonts)
|
|
4239
4321
|
return;
|
|
4240
|
-
if (document.querySelector('
|
|
4322
|
+
if (!document.querySelector('script[src^="/__bounded/"]'))
|
|
4241
4323
|
return;
|
|
4242
|
-
const
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
document.head.append(pre1, pre2, link);
|
|
4324
|
+
const registered = new Set();
|
|
4325
|
+
document.fonts.forEach((face) => registered.add(face.family.replace(/^["']|["']$/g, "")));
|
|
4326
|
+
for (const { family, url, weight } of WIDGET_FONT_FACES) {
|
|
4327
|
+
if (registered.has(family))
|
|
4328
|
+
continue;
|
|
4329
|
+
// Against the page's origin, not its base URL: a <base href> elsewhere must not move the fetch off this origin.
|
|
4330
|
+
const face = new FontFace(family, `url("${location.origin}${url}") format("woff2")`, { weight, display: "swap" });
|
|
4331
|
+
document.fonts.add(face);
|
|
4332
|
+
// A face that cannot load is taken back out; the font stack falls back to the next face.
|
|
4333
|
+
face.load().catch(() => { document.fonts.delete(face); });
|
|
4334
|
+
}
|
|
4254
4335
|
}
|
|
4255
4336
|
|
|
4256
4337
|
// turnkey-wallet-widget.ts - runs one Turnkey signer exchange inside the shared
|
|
@@ -6270,7 +6351,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6270
6351
|
// manager as legacy email sessions. Human login should be started
|
|
6271
6352
|
// with loginWithRedirect(); this provider is kept as the restore and
|
|
6272
6353
|
// logout surface for those sessions.
|
|
6273
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-
|
|
6354
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./email-auth-provider-DeORQbTK.js'); })).EmailAuthProvider();
|
|
6274
6355
|
break;
|
|
6275
6356
|
case "phantom": {
|
|
6276
6357
|
// First-class Solana WALLET LOGIN (the poof/TaroBase-style "connect
|
|
@@ -6312,7 +6393,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6312
6393
|
// (bounded-login-widget.ts), so registration never counts as
|
|
6313
6394
|
// evidence the user has a wallet.
|
|
6314
6395
|
await ensureSolanaMobileWalletRegistered(config, configuredNetwork);
|
|
6315
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6396
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
|
|
6316
6397
|
currentAuthProvider = new InjectedWalletProvider(resolveInjectedWalletConfig(config), rpcUrl, configuredNetwork);
|
|
6317
6398
|
break;
|
|
6318
6399
|
}
|
|
@@ -6325,7 +6406,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6325
6406
|
// Selecting authMethod:'evm-wallet' IS the opt-in — pass evmWalletConfig
|
|
6326
6407
|
// to point at a specific wallet or set chainId/domain.
|
|
6327
6408
|
const evmWalletConfig = ((_a = config.evmWalletConfig) !== null && _a !== void 0 ? _a : {});
|
|
6328
|
-
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-
|
|
6409
|
+
const { InjectedEvmWalletProvider } = await Promise.resolve().then(function () { return require('./injected-evm-wallet-provider-D06arDQD.js'); });
|
|
6329
6410
|
currentAuthProvider = new InjectedEvmWalletProvider(evmWalletConfig);
|
|
6330
6411
|
break;
|
|
6331
6412
|
}
|
|
@@ -6350,7 +6431,7 @@ async function getAuthProvider(config, fromStorage = false) {
|
|
|
6350
6431
|
break;
|
|
6351
6432
|
case "guest":
|
|
6352
6433
|
// Anonymous auth: a device-local ed25519 keypair signs the challenge.
|
|
6353
|
-
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
6434
|
+
currentAuthProvider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-5bX-xt6K.js'); })).GuestAuthProvider();
|
|
6354
6435
|
break;
|
|
6355
6436
|
}
|
|
6356
6437
|
if (!currentAuthProvider) {
|
|
@@ -6412,7 +6493,7 @@ async function signInAnonymously() {
|
|
|
6412
6493
|
// Lazy-load the guest provider so its ed25519/web3 dependencies stay out of
|
|
6413
6494
|
// the main bundle for data-only apps. Specifier is a static string literal
|
|
6414
6495
|
// so bundle-splitting can see it.
|
|
6415
|
-
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-
|
|
6496
|
+
const provider = new (await Promise.resolve().then(function () { return require('./guest-auth-provider-5bX-xt6K.js'); })).GuestAuthProvider();
|
|
6416
6497
|
setAuthLoading(true); // reflect "signing in…" while the guest keypair session is minted
|
|
6417
6498
|
// adoptSessionProvider awaits only getConfig() (already resolved here) and then
|
|
6418
6499
|
// runs every write - provider/method/config/marker/user - in one synchronous
|
|
@@ -6583,7 +6664,7 @@ function ensureSharedWalletLoginReady() {
|
|
|
6583
6664
|
if (!sharedWalletReady) {
|
|
6584
6665
|
sharedWalletReady = (async () => {
|
|
6585
6666
|
await core.getConfig();
|
|
6586
|
-
await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6667
|
+
await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
|
|
6587
6668
|
})().catch((error) => {
|
|
6588
6669
|
sharedWalletReady = null;
|
|
6589
6670
|
throw error;
|
|
@@ -6686,7 +6767,7 @@ async function loginWithWallet(options) {
|
|
|
6686
6767
|
await ensureSharedWalletLoginReady();
|
|
6687
6768
|
else
|
|
6688
6769
|
await ensureWalletLoginReady();
|
|
6689
|
-
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-
|
|
6770
|
+
const { InjectedWalletProvider } = await Promise.resolve().then(function () { return require('./injected-wallet-provider-B9jvzDM5.js'); });
|
|
6690
6771
|
// Keep the RAW wallet provider: the offchain wrapper forwards only a fixed
|
|
6691
6772
|
// set of methods, so cleanup below must speak to the provider that actually
|
|
6692
6773
|
// holds the config rather than to whatever is wrapping it.
|
|
@@ -7053,6 +7134,13 @@ function registerStorageBridge() {
|
|
|
7053
7134
|
void syncStoredSession().catch((error) => console.warn('Bounded session synchronization failed:', error));
|
|
7054
7135
|
});
|
|
7055
7136
|
}
|
|
7137
|
+
function sameSessionIdentity(next, previous) {
|
|
7138
|
+
if (!next || !previous)
|
|
7139
|
+
return false;
|
|
7140
|
+
const a = core.deriveUserIdentityFromIdToken(next);
|
|
7141
|
+
const b = core.deriveUserIdentityFromIdToken(previous);
|
|
7142
|
+
return !!a.id && a.id === b.id && a.address === b.address && a.email === b.email && a.evmAddress === b.evmAddress;
|
|
7143
|
+
}
|
|
7056
7144
|
async function syncStoredSession() {
|
|
7057
7145
|
const config = initializedConfig;
|
|
7058
7146
|
if (!config)
|
|
@@ -7061,6 +7149,18 @@ async function syncStoredSession() {
|
|
|
7061
7149
|
const issuer = core.WebSessionManager.getIssuer();
|
|
7062
7150
|
if (token === observedIdToken && issuer === observedIssuer)
|
|
7063
7151
|
return;
|
|
7152
|
+
// Another tab refreshed this same session (tokens rotate every few minutes):
|
|
7153
|
+
// who is signed in did not change, so keep the user and its live reads, whose
|
|
7154
|
+
// sockets take the new token on their own, instead of hiding and restoring it.
|
|
7155
|
+
if (currentUser && issuer === observedIssuer && sameSessionIdentity(token, observedIdToken)) {
|
|
7156
|
+
const record = await core.WebSessionManager.readSessionWithGeneration();
|
|
7157
|
+
if (config !== initializedConfig || core.WebSessionManager.getIdToken() !== token)
|
|
7158
|
+
return;
|
|
7159
|
+
if ((record === null || record === void 0 ? void 0 : record.idToken) === token && (!record.appId || record.appId === config.appId)) {
|
|
7160
|
+
observedIdToken = token;
|
|
7161
|
+
return;
|
|
7162
|
+
}
|
|
7163
|
+
}
|
|
7064
7164
|
observedIdToken = token;
|
|
7065
7165
|
observedIssuer = issuer;
|
|
7066
7166
|
const generation = ++initializationGeneration;
|
|
@@ -7557,7 +7657,9 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
|
|
|
7557
7657
|
// mobile adapter fills DEFAULT_FEATURES in exactly that case. So an empty list
|
|
7558
7658
|
// means none, and reading it as "everything" picks an account that cannot sign
|
|
7559
7659
|
// and fails at the wallet instead of here.
|
|
7560
|
-
|
|
7660
|
+
// The mobile adapter hands a wallet app's own feature names through
|
|
7661
|
+
// untranslated, so each name is read as its Wallet Standard equivalent.
|
|
7662
|
+
const accountSupports = (account, feature) => account.features.some((f) => walletStandardFeatureName(f) === feature);
|
|
7561
7663
|
const pickSolanaAccount = (accounts) => {
|
|
7562
7664
|
// With a network configured, an account that does not support it is not a
|
|
7563
7665
|
// usable account: `WalletAccount.chains` is what that account can sign for,
|
|
@@ -7632,13 +7734,23 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
|
|
|
7632
7734
|
} }, (hasFeature(wallet, SolanaSignIn)
|
|
7633
7735
|
? {
|
|
7634
7736
|
async signIn(input) {
|
|
7635
|
-
|
|
7636
|
-
if (!accountSupports(acc, SolanaSignIn))
|
|
7637
|
-
throw new Error("Wallet account does not support solana:signIn");
|
|
7737
|
+
var _a;
|
|
7638
7738
|
const sign = feature(wallet, SolanaSignIn);
|
|
7639
7739
|
if (!sign)
|
|
7640
7740
|
throw new Error("Wallet does not support solana:signIn");
|
|
7741
|
+
const open = currentAccount();
|
|
7742
|
+
if (open && !accountSupports(open, SolanaSignIn))
|
|
7743
|
+
throw new Error("Wallet account does not support solana:signIn");
|
|
7744
|
+
if (solanaMobileWalletAnswersSignInFromCache(wallet.name)) {
|
|
7745
|
+
// Drop the cached authorization so this sign-in is performed by the
|
|
7746
|
+
// wallet app, with its payload, rather than answered from a record
|
|
7747
|
+
// that holds no sign-in result or an earlier sign-in's spent nonce.
|
|
7748
|
+
// Local to the page: the adapter's disconnect opens nothing.
|
|
7749
|
+
await ((_a = feature(wallet, StandardDisconnect)) === null || _a === void 0 ? void 0 : _a.disconnect());
|
|
7750
|
+
}
|
|
7641
7751
|
const [out] = await sign.signIn(input);
|
|
7752
|
+
if (!out)
|
|
7753
|
+
throw new Error("Wallet returned no sign-in result");
|
|
7642
7754
|
return { account: { address: out.account.address }, signedMessage: out.signedMessage, signature: out.signature };
|
|
7643
7755
|
},
|
|
7644
7756
|
}
|
|
@@ -8088,8 +8200,8 @@ const CARD_CSS = `
|
|
|
8088
8200
|
--line:rgba(232,230,222,.08);--line-strong:rgba(232,230,222,.16);
|
|
8089
8201
|
--text:#e8e6de;--dim:#9b9991;--faint:#85837c;
|
|
8090
8202
|
--green:#58c98f;--green-bg:rgba(88,201,143,.09);--green-line:rgba(88,201,143,.28);--red:#ec8488;
|
|
8091
|
-
--disp:"Newsreader","Iowan Old Style",Georgia,serif;
|
|
8092
|
-
--body:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
|
|
8203
|
+
--disp:"Bounded Newsreader","Newsreader","Iowan Old Style",Georgia,serif;
|
|
8204
|
+
--body:"Bounded Schibsted Grotesk","Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
|
|
8093
8205
|
position:relative;padding:34px 32px 20px;color:var(--text);font-family:var(--body);
|
|
8094
8206
|
-webkit-font-smoothing:antialiased}
|
|
8095
8207
|
.x{position:absolute;top:20px;right:24px;border:0;background:transparent;color:var(--faint);
|
|
@@ -8210,6 +8322,17 @@ function discoverWallets(configuredNetwork) {
|
|
|
8210
8322
|
// beats a click that does nothing, which is what "one at a time" looks like from
|
|
8211
8323
|
// the outside.
|
|
8212
8324
|
const BUSY_MSG = "A sign-in is already in progress - finish or cancel it first.";
|
|
8325
|
+
// Shown instead of an empty card when no lane can be offered (wallet-only app,
|
|
8326
|
+
// no wallet in this browser). A phone browser never sees installed wallet apps
|
|
8327
|
+
// as injected providers, so the honest advice there is a different browser,
|
|
8328
|
+
// not "install a wallet".
|
|
8329
|
+
function noLaneCopy(mobile) {
|
|
8330
|
+
return mobile
|
|
8331
|
+
? "No wallet is available in this browser. Open this page in your wallet app's " +
|
|
8332
|
+
"browser, or on a desktop browser with a wallet extension, then try again."
|
|
8333
|
+
: "No wallet was found in this browser. Install a Solana wallet extension such as " +
|
|
8334
|
+
"Phantom or Solflare, reload the page, then try again.";
|
|
8335
|
+
}
|
|
8213
8336
|
const METHOD_LABEL = {
|
|
8214
8337
|
google: "Continue with Google",
|
|
8215
8338
|
apple: "Continue with Apple",
|
|
@@ -8551,12 +8674,9 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8551
8674
|
cancelPendingOpens();
|
|
8552
8675
|
};
|
|
8553
8676
|
m.onBackdrop = cancel;
|
|
8554
|
-
const style = el("style");
|
|
8555
|
-
style.textContent = CARD_CSS;
|
|
8556
8677
|
let emailDraft = "";
|
|
8557
8678
|
const renderChoose = (initialError) => {
|
|
8558
8679
|
const card = el("div", "c");
|
|
8559
|
-
card.appendChild(style.cloneNode(true));
|
|
8560
8680
|
const x = el("button", "x", "Close");
|
|
8561
8681
|
x.type = "button";
|
|
8562
8682
|
x.setAttribute("aria-label", "Close");
|
|
@@ -8773,6 +8893,24 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8773
8893
|
});
|
|
8774
8894
|
};
|
|
8775
8895
|
}
|
|
8896
|
+
// A card with no lane at all. It happens when an app asks for wallet-only
|
|
8897
|
+
// (`methods: []`, `wallet: true`) and this browser has no wallet to offer:
|
|
8898
|
+
// no injected wallet, and no Solana Mobile wallet (off-Android, or the app
|
|
8899
|
+
// never installed the adapter). A blank card between the title and the
|
|
8900
|
+
// footer was the shipped behaviour, and it reads as "the site is broken"
|
|
8901
|
+
// to the person and tells the developer nothing. Say what is missing on
|
|
8902
|
+
// screen, and name the usual cause once in the console, where the
|
|
8903
|
+
// developer's own preview run will show it.
|
|
8904
|
+
if (!hasEmail && social.length === 0 && !walletEnabled) {
|
|
8905
|
+
card.appendChild(el("p", "sub", noLaneCopy(detectMobile())));
|
|
8906
|
+
console.warn("[Bounded] openBoundedWidget has no sign-in lane to show: the app asked for " +
|
|
8907
|
+
"no email or social method and no wallet is available in this browser. " +
|
|
8908
|
+
(offerMobile
|
|
8909
|
+
? "On Android the Solana Mobile wallet is offered only when the app installs " +
|
|
8910
|
+
"'@solana-mobile/wallet-standard-mobile' (see the warning above if registration failed); "
|
|
8911
|
+
: "") +
|
|
8912
|
+
"Add a method, or make sure wallet login is enabled and the mobile adapter is installed.");
|
|
8913
|
+
}
|
|
8776
8914
|
card.appendChild(status);
|
|
8777
8915
|
const foot = el("div", "foot");
|
|
8778
8916
|
const poweredBy = el("a", undefined, "Powered by Bounded");
|
|
@@ -8783,11 +8921,13 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8783
8921
|
card.appendChild(foot);
|
|
8784
8922
|
return card;
|
|
8785
8923
|
};
|
|
8786
|
-
// Solana Mobile leaves the page to sign:
|
|
8787
|
-
// started login, so requesting the
|
|
8788
|
-
// no transient activation left,
|
|
8789
|
-
//
|
|
8790
|
-
//
|
|
8924
|
+
// Solana Mobile leaves the page to sign in: the nonce fetch that precedes
|
|
8925
|
+
// the sign-in outlives the tap that started login, so requesting the
|
|
8926
|
+
// sign-in straight afterwards runs with no transient activation left,
|
|
8927
|
+
// Chrome blocks the `solana-wallet:` intent navigation, and the protocol
|
|
8928
|
+
// reports the wallet as missing. Collect a fresh tap on its OWN view (one
|
|
8929
|
+
// wallet trip: sign-in authorizes and signs in the same step, there is no
|
|
8930
|
+
// connect before it) - never by adding a listener to a button that
|
|
8791
8931
|
// already starts a login, which would run both handlers on that tap and
|
|
8792
8932
|
// kick off a duplicate login beside the one waiting for the gesture.
|
|
8793
8933
|
// Injected wallets sign in-page and get no extra step.
|
|
@@ -8819,7 +8959,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8819
8959
|
const renderSignInGesture = (choice, done) => {
|
|
8820
8960
|
var _a;
|
|
8821
8961
|
const card = el("div", "c");
|
|
8822
|
-
card.appendChild(style.cloneNode(true));
|
|
8823
8962
|
const x = el("button", "x", "Close");
|
|
8824
8963
|
x.type = "button";
|
|
8825
8964
|
x.setAttribute("aria-label", "Close");
|
|
@@ -8840,7 +8979,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8840
8979
|
};
|
|
8841
8980
|
const renderWallets = (initialError) => {
|
|
8842
8981
|
const card = el("div", "c");
|
|
8843
|
-
card.appendChild(style.cloneNode(true));
|
|
8844
8982
|
const back = el("button", "back", "\u2190 Back");
|
|
8845
8983
|
back.type = "button";
|
|
8846
8984
|
// Leaving the wallet list supersedes any attempt still preparing, so it
|
|
@@ -8920,7 +9058,6 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8920
9058
|
// experience still feels native; the code input, sealing, and verify all live behind the frame.
|
|
8921
9059
|
const renderOtpFrame = (handle) => {
|
|
8922
9060
|
const card = el("div", "c");
|
|
8923
|
-
card.appendChild(style.cloneNode(true));
|
|
8924
9061
|
const back = el("button", "back", "\u2190 Back");
|
|
8925
9062
|
back.type = "button";
|
|
8926
9063
|
card.appendChild(back);
|
|
@@ -8967,7 +9104,7 @@ async function prepareAndOpen(opts, pending) {
|
|
|
8967
9104
|
// land after a newer open has taken over the DOM.
|
|
8968
9105
|
if (!owner.owns())
|
|
8969
9106
|
return;
|
|
8970
|
-
mountContent(m, node);
|
|
9107
|
+
mountContent(m, node, CARD_CSS);
|
|
8971
9108
|
requestAnimationFrame(() => {
|
|
8972
9109
|
if (owner.owns())
|
|
8973
9110
|
fitPanelToContent(m);
|
|
@@ -11359,4 +11496,4 @@ exports.useAuth = useAuth;
|
|
|
11359
11496
|
exports.useBuildRun = useBuildRun;
|
|
11360
11497
|
exports.useQuery = useQuery;
|
|
11361
11498
|
exports.waitForAuthReady = waitForAuthReady;
|
|
11362
|
-
//# sourceMappingURL=index-
|
|
11499
|
+
//# sourceMappingURL=index-BZ0X1Z9X.js.map
|