import type { Announcement, AnnouncementBar, CartItem, CashbackPreview, CatalogFacets, CatalogLetterCounts, CatalogSection, CatalogSitemapRoutesResponse, Category, CategoryInfo, CheckoutCreateOptions, CheckoutItemInput, CheckoutPreview, CheckoutPreviewOptions, CheckoutRequest, CheckoutResponse, CheckoutStatus, CmsArticleListResponse, CmsArticleLocale, CmsArticleResponse, CmsArticleType, CodeReadinessResult, CoinPurchaseResult, CoinPurchaseStatus, CoinRedeemResult, CoinRedemption, CoinReward, CoinTransaction, CoinWallet, CoinWinner, CompleteWithBalanceResult, Conversation, ConversationDetail, CouponResult, CustomerCancelResult, DailyBonusClaimResult, DailyBonusStatus, DeliveryHelpResponse, DeliveryImageUpload, ExchangeRates, FaqListResponse, Favorite, Game, GameDetail, GameRequestList, GiftCard, GuestCheckoutSessionRequest, GuestCheckoutSessionResponse, LegalDocument, LevelStatus, MarketingTrackVisitRequest, MarketingTrackVisitResult, MarketingVisitRefs, Notification, Order, OrderKeyState, OrderKeyStateResult, PackRequest, PackRequestGame, PackRequestPayResponse, PagedGamesResponse, PaginatedResponse, PaymentInfo, PaymentMethod, PlatformInfo, Product, ProductFilters, ProfileSummary, PublicCoupon, PublicSupportRequest, PublicSupportResponse, Quest, QuestCompleteResult, RecentPurchase, ReferralCommission, ReferralLink, ReferralPerformance, ReferralStats, ReferralTransferResult, ReorderItemResult, Review, ReviewCreateOptions, ReviewCreateResult, ReviewGuestCreateOptions, ReviewGuestCreateResult, ReviewPolicy, ReviewProof, ReviewStats, ScreenshotsResponse, SearchResult, SeoSitemapEntry, SiteConfig, SiteStats, SiteUIConfig, SuperpassGameResponse, SuperpassGameSummary, SuperpassUserVerification, SupportCallAdminResult, SupportMessage, SupportThread, SystemRequirementsResponse, TelegramAuthResponse, TelegramBotLoginOptions, TelegramInitResponse, TelegramWidgetRenderOptions, TelegramWidgetUser, TopupCreateOptions, TopupMethod, TopupResponse, TopupStatus, Transaction, User, UserBalance, WebPushSubscriptionInput } from "./types"; /** * Supported storefront locales — extend as new languages land. * "es" (Spanish) and "pt-br" (Brazilian Portuguese) are LATAM: the API maps * them to the `latam` payment region, so a client created with one of these * is not offered Russia-only payment rails. Extend as new languages land. * * "fa" (Persian) is recognised by every API resolver as of the fa layer-0 * change. It is RTL, and no tenant lists it in `sites.additional_locales` * yet — so setting it today yields the API's untranslated fallbacks rather * than Persian content. * * ⚠ KNOWN GAP, pre-existing and NOT introduced by the fa work: "uk" is * missing from this union even though the API treats it as first-class and * the kazakevich tenant's default_locale IS uk. A uk storefront currently * needs a cast to set it. Widening is type-only (the runtime already accepts * any string) but is left out of the fa change on purpose — it is a separate * decision about a live tenant. */ export type SdkLocale = "ru" | "en" | "es" | "pt-br" | "fa"; /** * ISO-4217 codes the API can quote prices in. Matches the server-side * `DisplayCurrency` union in `apps/api/src/utils/currency.ts`. RUB is * the default when nothing is configured; USD is the canonical base * price in the DB. */ export type SdkCurrency = "RUB" | "USD" | "EUR" | "GBP" | "KZT" | "UAH" | "TRY" | "BRL" | "ARS" | "INR" | "PLN" | "CZK"; export interface GameCoreOptions { /** Site API key (gc_live_xxx or gc_test_xxx) */ apiKey: string; /** Base URL of GameCore API (e.g. https://api.gamecore-api.tech) */ baseUrl: string; /** Called on 401 — use to redirect to login */ onAuthError?: () => void; /** * Default locale for catalog/CMS responses. When set, every request * sends an `Accept-Language` header so the API returns localized * name/description fields without each call passing `locale=` itself. * Per-call `locale` arguments still take precedence over the default. * Omit to keep the legacy behaviour (server falls back to "ru"). */ locale?: SdkLocale; /** * Default display currency for catalog product prices. When set, * every request sends an `X-Currency` header so the API converts * `price` / `priceWithoutDiscount` into that ISO-4217 code (using * live FX rates) and stamps the resolved code on each product * response under the `currency` field. * * Per-call `?currency=` overrides this default. Omit to keep RUB * (the legacy default — every existing storefront keeps working * without a code change). */ currency?: SdkCurrency; } export declare class GameCoreClient { private apiKey; private baseUrl; private onAuthError?; private defaultLocale?; private defaultCurrency?; constructor(options: GameCoreOptions); /** * Switch the client's default locale at runtime — useful for a * storefront language switcher that should not have to re-instantiate * the client. */ setLocale(locale: SdkLocale | undefined): void; /** Current default locale (undefined when none set). */ getLocale(): SdkLocale | undefined; /** * Switch the client's default display currency at runtime — wire to * a storefront currency picker so the next product fetch comes back * already converted, without re-instantiating the client. */ setCurrency(currency: SdkCurrency | undefined): void; /** Current default currency (undefined when none set → API returns RUB). */ getCurrency(): SdkCurrency | undefined; private request; site: { /** Get site configuration (modules, auth methods, payments, currency) */ getConfig: () => Promise; /** Get current exchange rates (USD→RUB and others) */ getRates: () => Promise; /** Get legal document by type (privacy, terms, etc.) */ getLegal: (type: string, locale?: string) => Promise; /** Get site statistics for trust signals (cached 5 min on server) */ getStats: () => Promise; /** Get social proof — recent purchases for trust display */ getSocialProof: () => Promise<{ recentPurchases: Array<{ gameName: string; timeAgo: string; }>; }>; /** * Public "recent purchases" feed for the homepage social-proof * ticker. Returns the last week of completed orders, deduped to * one row per order, privacy-masked (first name, masked * username, or "Покупатель"). Distinct from `getSocialProof()` * — that one is a thinner `{gameName,timeAgo}[]` projection * powered by the same data but shaped for a different widget. * * `limit` is clamped server-side to [1, 30]; default 15. */ getRecentPurchases: (params?: { limit?: number; }) => Promise; /** Get theme config (white-label colors, fonts, borderRadius) */ getThemeConfig: () => Promise<{ colors: Record; borderRadius: string; font: string; }>; /** Get site translations for a locale (Record) */ getTranslations: (locale?: string) => Promise>; /** Get site UI config (header, footer, nav, trust pills) */ getUIConfig: () => Promise; /** * Per-site allowlist of partner origins permitted to iframe the * storefront's checkout/widget pages. Wave 5 #58, available * since gamecore-api 2026-05-01. * * Storefronts feed this list into their own * `Content-Security-Policy: frame-ancestors` directive — this * SDK call only fetches the data, it does not set the header * itself (the storefront's edge / Next.js middleware does). */ getEmbedAllowlist: () => Promise; /** Get cookie consent config */ getCookieConsent: () => Promise<{ enabled: boolean; text: string; policyUrl: string; }>; /** Get per-site catalog sections (category tabs config) */ getCatalogSections: () => Promise; /** * Get active hero banners for the storefront carousel. * Each banner carries optional visual fields plus a `url` * destination — `null` means the banner is display-only and * should not be rendered as a link. */ getBanners: () => Promise<{ id: number; title: string | null; description: string | null; imageUrl: string | null; color: string | null; url: string | null; scope: string; priority: number; }[]>; /** Get announcement bar settings (text, link, enabled) */ getAnnouncementBar: () => Promise; /** * Get sitemap data for self-generated storefront sitemaps. * Returns `{ slug, updatedAt }` for every game visible on * this site. Use `updatedAt` as `lastModified` in Next.js * `sitemap.ts` so Google's crawler respects unchanged pages * instead of stamping the whole catalog with `new Date()`. * * 🔴 Since 0.71.0 `slug` is the tenant's OWN url on a site with * per-site catalog pages — an ADDRESS, not the platform identity. Emit * it as-is; see {@link SeoSitemapEntry.slug}. */ getSitemapData: () => Promise; /** * Submit a "please add this game" request. Works for both * authenticated users (the server attaches the user id so * support can reach back) and anonymous visitors. * * Rate-limited server-side. The optional `website` field is * a honeypot — leave it `undefined` in real code; the * storefront can render an invisible input under that name * so scrapers self-identify. * * @returns The new request id and a success flag. A filled * honeypot still returns `success: true` with * `requestId: -1` so bots cannot distinguish a real save * from a silent drop. */ requestGame: (data: { gameName: string; comment?: string; gameUrl?: string; website?: string; }) => Promise<{ success: boolean; requestId: number; }>; /** * Get the per-site review-payout policy. Storefronts use this on * the order success page to decide whether to advertise a * cashback bonus for posting a review, and to enforce the * minimum text length client-side before submission. */ getReviewPolicy: () => Promise; /** * Get FAQ entries for this site. Without `gameId`, returns all * active site-wide FAQ entries (rows with `gameId: null`). When * `gameId` is provided, returns ONLY entries scoped to that * game — site-wide entries are NOT included in the response. * Storefronts that want both site-wide and game-specific FAQ * on the same page must call this method twice and merge the * results client-side. `position` is the display order (lower * first); `gameId: null` marks site-wide entries. */ getFaq: (gameId?: number) => Promise; /** * List published CMS articles of a given type for the current * site. Returns a summary projection (no body) — call * `getArticle()` to fetch a single article's full content. * * `locale` defaults to the site's default locale on the * server (currently "ru") when omitted. `limit` is capped * server-side at 100; `offset` enables pagination. * * `type: "guide"` (SDK 0.48.0+) returns AI-generated game * guides — each summary carries `entityKind`/`entityId`/ * `entitySlug` linking it back to the SuperPass or canonical * game it's about. Other article types always return those * three fields as `null`. */ getArticles: (type: CmsArticleType, options?: { locale?: CmsArticleLocale; limit?: number; offset?: number; }) => Promise; /** * Fetch a single published CMS article by slug, in the requested * locale EXACTLY. * * 🔴 Behaviour change (SDK 0.69.0): the server used to fall back * to the RU article when the requested locale was missing. It no * longer does — a slug that exists only in RU now throws 404 for * `{ locale: "en" }` instead of returning the Russian body. This * is intentional: the old fallback served one body under two * locale URLs (duplicate content) and made hreflang advertise * translations that didn't exist. A storefront that relied on the * fallback to always render something must now either request * "ru" explicitly or treat 404 as "no translation yet" and skip * the URL in its hreflang/sitemap output. * * `article.locale` is therefore always the locale you asked for; * there is no fallback left to detect. * * Throws `GameCoreError(404)` when no published article matches * the requested type/slug/locale triple. */ getArticle: (type: CmsArticleType, slug: string, options?: { locale?: CmsArticleLocale; }) => Promise; }; auth: { /** Start Telegram auth flow → returns bot link for user to click */ initTelegram: () => Promise; /** Poll Telegram auth status until authenticated or expired */ pollTelegramStatus: (token: string, intervalMs?: number) => Promise; /** * Read the storefront's Telegram OpenID Connect config. Returns * { enabled: false, clientId: null } when the tenant hasn't set * up Web Login in BotFather (the SPA should fall back to the * deep-link flow). When enabled, hand `clientId` to telegram- * login.js to render the native consent card. */ getTelegramOidcConfig: () => Promise<{ enabled: boolean; clientId: string | null; }>; /** * Submit the RS256 id_token returned by telegram-login.js for * server-side JWKS verification. On success the backend sets an * auth cookie and returns the authenticated user, exactly like * the Mini App / Widget verifiers. Optional `ref` threads a * referral code through user creation on first login; optional * `mv` threads marketing visit refs the same way. */ telegramOidc: (idToken: string, ref?: string, mv?: MarketingVisitRefs) => Promise; /** * Verify Telegram Mini App initData and issue a session cookie. * Call this when your storefront is opened inside Telegram via the * bot's Mini App / Web App button — `window.Telegram.WebApp.initData` * is the raw URL-encoded string you should pass in. The backend * validates the HMAC signature against the bot token and mints a * normal auth cookie, so the rest of the site stays logged in. * Optional `ref` threads a referral code through user creation; * optional `mv` threads marketing visit refs the same way. */ verifyMiniApp: (initData: string, ref?: string, mv?: MarketingVisitRefs) => Promise; /** * Verify Telegram Login Widget payload (JSON POST variant) and * issue a session cookie. Use this when you embed the Login Widget * with `data-onauth` (JS callback) instead of `data-auth-url` * (full-page redirect) — pass the object the widget handed you * directly to this method. */ verifyTelegramWidget: (data: TelegramWidgetUser, ref?: string, mv?: MarketingVisitRefs) => Promise; /** * High-level helper: mount the official Telegram Login Widget into * your own DOM element and hand the resulting User to `onAuth` * after server-side HMAC verification. Browser-only. * * Compared to dropping the raw `