// VK Mini App SDK access via @vkontakte/vk-bridge. The bridge is imported lazily inside the // functions that need it — not at module top level — because the SDK reads browser globals on // import: the lazy import keeps the pure URL helpers below importable in the node test environment, // and code-splits the bridge into a chunk loaded only on the /vk/ entry. This wraps the subset the // app uses: launch detection, the signed launch parameters (for auth.vk) and the user's display name // (VKWebAppGetUserInfo, since VK omits it from the signed launch params). Every helper is safe to // call outside VK. async function bridge() { return (await import('@vkontakte/vk-bridge')).default; } /** * onVKPath reports whether the app is served under the dedicated VK entry path (/vk/). */ export function onVKPath(): boolean { if (typeof location === 'undefined') return false; return location.pathname.startsWith('/vk/'); } /** * vkLaunchParams returns the raw signed VK launch query string (the vk_* parameters plus sign) from * the page URL — the exact form the gateway verifies — or '' when the URL carries no signed launch * (an ordinary browser tab, or the /vk/ path opened directly). */ export function vkLaunchParams(): string { if (typeof location === 'undefined') return ''; const query = location.search.replace(/^\?/, ''); return new URLSearchParams(query).has('sign') ? query : ''; } /** * insideVK reports whether the app launched as a VK Mini App — the URL carries signed launch * parameters (an ordinary browser tab has none). */ export function insideVK(): boolean { return vkLaunchParams() !== ''; } /** * vkInit signals to the VK client that the Mini App has loaded (VKWebAppInit), dismissing VK's own * loading cover. Best-effort: it resolves even if the bridge is unavailable (outside VK), so the * caller can await it unconditionally. */ export async function vkInit(): Promise { try { await (await bridge()).send('VKWebAppInit', {}); } catch { // Outside VK there is no client to receive it; the launch continues regardless. } } /** * vkUserName fetches the launching user's display name via VKWebAppGetUserInfo, since VK omits it * from the signed launch params. Returns '' on any failure or outside VK, so the backend falls back * to a generated placeholder. The value is a cosmetic seed only — being unsigned, the gateway never * trusts it for identity. */ export async function vkUserName(): Promise { try { const u = await (await bridge()).send('VKWebAppGetUserInfo', {}); return [u.first_name, u.last_name].filter(Boolean).join(' ').trim(); } catch { return ''; } }