@looplay/sdk 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/auth/storage.ts","../src/auth/looplay-auth.ts","../src/apps/http.ts","../src/apps/service-client.ts","../src/apps/api-client.ts","../src/looplay-sdk.ts","../src/auth/providers/telegram-auth-provider.ts"],"names":["text","fetch"],"mappings":"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","file":"looplay-sdk.esm.js","sourcesContent":["export class LooplaySDKError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = 'LooplaySDKError';\n }\n}\n\nexport class NotInitializedError extends LooplaySDKError {\n constructor() {\n super('LooplaySDK not initialized. Call init({ gameId }) first.');\n this.name = 'NotInitializedError';\n }\n}\n\nexport class MissingBaseUrlError extends LooplaySDKError {\n constructor() {\n super('Missing baseUrl. Provide `baseUrl` to enable HTTP integration.');\n this.name = 'MissingBaseUrlError';\n }\n}\n\nexport class MissingAuthError extends LooplaySDKError {\n constructor() {\n super('Missing auth. Provide `auth` options to enable user login/session.');\n this.name = 'MissingAuthError';\n }\n}\n\nexport class NotAuthenticatedError extends LooplaySDKError {\n constructor() {\n super('Not authenticated. Login is required for this operation.');\n this.name = 'NotAuthenticatedError';\n }\n}\n","import type { AuthStorage } from './types';\n\nexport class MemoryAuthStorage implements AuthStorage {\n private readonly map = new Map<string, string>();\n\n async getItem(key: string): Promise<string | null> {\n return this.map.has(key) ? (this.map.get(key) as string) : null;\n }\n\n async setItem(key: string, value: string): Promise<void> {\n this.map.set(key, value);\n }\n\n async removeItem(key: string): Promise<void> {\n this.map.delete(key);\n }\n}\n\nexport class BrowserLocalStorageAuthStorage implements AuthStorage {\n async getItem(key: string): Promise<string | null> {\n if (typeof window === 'undefined' || !window.localStorage) return null;\n return window.localStorage.getItem(key);\n }\n\n async setItem(key: string, value: string): Promise<void> {\n if (typeof window === 'undefined' || !window.localStorage) return;\n window.localStorage.setItem(key, value);\n }\n\n async removeItem(key: string): Promise<void> {\n if (typeof window === 'undefined' || !window.localStorage) return;\n window.localStorage.removeItem(key);\n }\n}\n","import { LooplaySDKError } from '../errors';\nimport {\n type AuthEventName,\n type AuthLoginParams,\n type AuthProvider,\n type AuthStorage,\n type LooplayAuthOptions,\n type LooplaySession\n} from './types';\nimport { MemoryAuthStorage } from './storage';\n\nclass InvalidSessionError extends LooplaySDKError {\n constructor() {\n super('Invalid session returned by auth provider');\n this.name = 'InvalidSessionError';\n }\n}\n\ntype Listener = (session: LooplaySession | null) => void;\n\nexport class LooplayAuth {\n private readonly provider: AuthProvider;\n private readonly storage: AuthStorage;\n private readonly key: string;\n\n private session: LooplaySession | null = null;\n private readonly listeners = new Set<Listener>();\n\n constructor(options: LooplayAuthOptions) {\n this.provider = options.provider;\n this.storage = options.storage ?? new MemoryAuthStorage();\n this.key = `${options.storageKeyPrefix ?? 'looplay'}:auth:session`;\n }\n\n async init(): Promise<void> {\n await this.provider.init?.();\n await this.restoreFromStorage();\n\n // Keep provider in sync with restored session (if any).\n await this.provider.onSessionChanged?.(this.session);\n }\n\n getSession(): LooplaySession | null {\n return this.session;\n }\n\n async login(params?: AuthLoginParams): Promise<LooplaySession> {\n const result = await this.provider.login(params);\n\n if (!result?.session?.user?.id) {\n throw new InvalidSessionError();\n }\n\n await this.setSession(result.session, 'login');\n return result.session;\n }\n\n async logout(): Promise<void> {\n await this.provider.logout();\n await this.setSession(null, 'logout');\n }\n\n async getAccessToken(): Promise<string | undefined> {\n if (!this.session) return undefined;\n\n const now = Date.now();\n const isExpired =\n typeof this.session.expiresAt === 'number' && this.session.expiresAt <= now;\n\n if (!isExpired) return this.session.accessToken;\n\n if (!this.provider.refresh) return this.session.accessToken;\n\n const refreshed = await this.provider.refresh();\n const next = { ...this.session, ...refreshed };\n await this.setSession(next, 'sessionChanged');\n\n return next.accessToken;\n }\n\n on(eventName: AuthEventName, listener: Listener): () => void {\n // eventName reserved for future filtering; for now notify on any change\n void eventName;\n\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private async restoreFromStorage(): Promise<void> {\n const raw = await this.storage.getItem(this.key);\n if (!raw) return;\n\n try {\n const parsed = JSON.parse(raw) as LooplaySession;\n if (parsed?.user?.id) {\n this.session = parsed;\n }\n } catch {\n // ignore corrupted cache\n await this.storage.removeItem(this.key);\n }\n }\n\n private async setSession(next: LooplaySession | null, event: AuthEventName): Promise<void> {\n this.session = next;\n\n await this.provider.onSessionChanged?.(this.session);\n\n if (next) {\n await this.storage.setItem(this.key, JSON.stringify(next));\n } else {\n await this.storage.removeItem(this.key);\n }\n\n for (const listener of this.listeners) {\n listener(this.session);\n }\n\n // reserved for future event-specific hooks\n void event;\n }\n}\n","export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchLike;\n defaultHeaders?: Record<string, string>;\n}\n\nexport class HttpError extends Error {\n readonly status: number;\n readonly bodyText?: string;\n\n constructor(message: string, status: number, bodyText?: string) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.bodyText = bodyText;\n }\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly fetchFn: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '');\n this.fetchFn = options.fetch ?? fetch;\n this.defaultHeaders = options.defaultHeaders ?? {};\n }\n\n async request<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE',\n path: string,\n options?: {\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string | undefined>;\n bearerToken?: string;\n body?: unknown;\n }\n ): Promise<T> {\n const url = this.buildUrl(path, options?.query);\n\n const headers: Record<string, string> = this.mergeHeaders(\n this.defaultHeaders,\n options?.headers\n );\n\n if (options?.bearerToken) {\n headers.Authorization = `Bearer ${options.bearerToken}`;\n }\n\n let body: BodyInit | undefined;\n if (options?.body !== undefined) {\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json';\n body = JSON.stringify(options.body);\n }\n\n const res = await this.fetchFn(url, { method, headers, body });\n\n if (!res.ok) {\n const text = await this.safeText(res);\n throw new HttpError(`HTTP ${res.status} ${res.statusText}`, res.status, text);\n }\n\n // Some endpoints may return empty body.\n const text = await this.safeText(res);\n if (!text) return undefined as T;\n\n return JSON.parse(text) as T;\n }\n\n private mergeHeaders(\n ...sources: Array<Record<string, string | undefined> | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const src of sources) {\n if (!src) continue;\n for (const [key, value] of Object.entries(src)) {\n if (value === undefined) continue;\n result[key] = value;\n }\n }\n\n return result;\n }\n\n private buildUrl(\n path: string,\n query?: Record<string, string | number | boolean | undefined>\n ): string {\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${this.baseUrl}${normalizedPath}`);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) continue;\n url.searchParams.set(key, String(value));\n }\n }\n\n return url.toString();\n }\n\n private async safeText(res: Response): Promise<string> {\n try {\n return await res.text();\n } catch {\n return '';\n }\n }\n}\n","import { HttpClient, type HttpClientOptions } from './http';\nimport type {\n AuthResultDto,\n EmitGameEventRequest,\n EmitGameEventResponse,\n PagingResponse,\n RefreshTokenRequest,\n TelegramLoginRequest,\n TrackGamePlayRequest,\n TrackMatchEndRequest,\n} from './LooplaySDK.types';\n\nexport interface ServiceClientOptions extends HttpClientOptions {}\n\n/**\n * Low-level HTTP client that maps 1:1 to backend routes.\n * Methods requiring user auth accept `bearerToken` explicitly.\n */\nexport class ServiceClient {\n private readonly http: HttpClient;\n\n constructor(options: ServiceClientOptions) {\n this.http = new HttpClient(options);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Auth\n // ─────────────────────────────────────────────────────────────────────────────\n\n async telegramLogin(telegramInitData: string): Promise<AuthResultDto> {\n const body: TelegramLoginRequest = { telegramInitData };\n return this.http.request('POST', '/account/telegram-login', { body });\n }\n\n async refresh(refreshToken: string): Promise<AuthResultDto> {\n const body: RefreshTokenRequest = { refreshToken };\n return this.http.request('POST', '/account/refresh', { body });\n }\n\n async logout(refreshToken: string): Promise<boolean> {\n const body: RefreshTokenRequest = { refreshToken };\n return this.http.request('POST', '/account/logout', { body });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Games\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listGames(query?: Record<string, any>): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/games', { query });\n }\n\n async getGameDetail(gameId: string, bearerToken: string): Promise<any> {\n return this.http.request('GET', `/games/${encodeURIComponent(gameId)}`, {\n bearerToken,\n });\n }\n\n async listRecentPlayed(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/games/recent-play', { bearerToken, query });\n }\n\n async trackPlay(\n bearerToken: string,\n gameId: string,\n playTimeSeconds?: number\n ): Promise<boolean> {\n const body: TrackGamePlayRequest = { playTimeSeconds };\n await this.http.request('POST', `/games/${encodeURIComponent(gameId)}/play`, {\n bearerToken,\n body,\n });\n return true;\n }\n\n async trackMatchEnd(\n bearerToken: string,\n gameId: string,\n body: TrackMatchEndRequest\n ): Promise<boolean> {\n await this.http.request('POST', `/games/${encodeURIComponent(gameId)}/end`, {\n bearerToken,\n body,\n });\n return true;\n }\n\n async emitGameEvent(\n bearerToken: string,\n gameId: string,\n body: EmitGameEventRequest\n ): Promise<EmitGameEventResponse> {\n return this.http.request('POST', `/games/${encodeURIComponent(gameId)}/emit`, {\n bearerToken,\n body,\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Balance\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getBalances(bearerToken: string, query?: Record<string, any>): Promise<any> {\n return this.http.request('GET', '/balance', { bearerToken, query });\n }\n\n async getBalanceHistory(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/balance/history', { bearerToken, query });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // User\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getMyProfile(bearerToken: string): Promise<any> {\n return this.http.request('GET', '/user/profile', { bearerToken });\n }\n\n async getMyBalance(bearerToken: string): Promise<any> {\n return this.http.request('GET', '/user/balance', { bearerToken });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Referrals\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listReferrals(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/referrals', { bearerToken, query });\n }\n\n async setReferral(bearerToken: string, body: Record<string, any>): Promise<boolean> {\n return this.http.request('POST', '/referrals/set', { bearerToken, body });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tasks / Quests\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listTasks(bearerToken: string): Promise<any[]> {\n return this.http.request('GET', '/task', { bearerToken });\n }\n\n async listFinishedTasks(bearerToken: string): Promise<any[]> {\n return this.http.request('GET', '/task/finished', { bearerToken });\n }\n\n async startTask(bearerToken: string, body: Record<string, any>): Promise<any> {\n return this.http.request('POST', '/task/start', { bearerToken, body });\n }\n\n async claimTask(bearerToken: string, body: Record<string, any>): Promise<any> {\n return this.http.request('POST', '/task/claim', { bearerToken, body });\n }\n\n async getPlatformQuests(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<any> {\n return this.http.request('GET', '/quest/platform', { bearerToken, query });\n }\n\n async getCampaignQuests(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<any> {\n return this.http.request('GET', '/quest/campaign', { bearerToken, query });\n }\n\n async claimQuest(bearerToken: string, questProgressId: string): Promise<any> {\n return this.http.request('POST', `/quest/${encodeURIComponent(questProgressId)}/claim`, {\n bearerToken,\n });\n }\n\n async claimMilestone(\n bearerToken: string,\n milestoneId: string,\n body: Record<string, any>\n ): Promise<any> {\n return this.http.request(\n 'POST',\n `/quest/milestone/${encodeURIComponent(milestoneId)}/claim`,\n {\n bearerToken,\n body,\n }\n );\n }\n}\n","import { MissingBaseUrlError, NotAuthenticatedError } from '../errors';\nimport type {\n EmitGameEventRequest,\n EmitGameEventResponse,\n GameEventKey,\n PagingResponse,\n TrackMatchEndRequest,\n} from './LooplaySDK.types';\nimport { ServiceClient } from './service-client';\nimport type { ServiceClientOptions } from './service-client';\n\nexport interface ApiClientOptions extends Omit<ServiceClientOptions, 'baseUrl'> {\n baseUrl?: string;\n getAccessToken?: () => Promise<string | undefined>;\n}\n\n/**\n * High-level API client that injects user auth automatically.\n */\nexport class ApiClient {\n private readonly raw: ServiceClient;\n private readonly getAccessToken?: () => Promise<string | undefined>;\n\n constructor(options: ApiClientOptions) {\n if (!options.baseUrl) throw new MissingBaseUrlError();\n\n this.raw = new ServiceClient({\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n defaultHeaders: options.defaultHeaders,\n });\n\n this.getAccessToken = options.getAccessToken;\n }\n\n /** Expose the underlying route-level client (requires manual bearerToken passing). */\n unsafeRaw(): ServiceClient {\n return this.raw;\n }\n\n // Public endpoints\n async listGames(query?: Record<string, any>): Promise<PagingResponse<any>> {\n return this.raw.listGames(query);\n }\n\n // Authenticated endpoints\n private async requireToken(): Promise<string> {\n const token = await this.getAccessToken?.();\n if (!token) throw new NotAuthenticatedError();\n return token;\n }\n\n async getGameDetail(gameId: string): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getGameDetail(gameId, token);\n }\n\n async listRecentPlayed(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.listRecentPlayed(token, query);\n }\n\n async trackPlay(gameId: string, playTimeSeconds?: number): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.trackPlay(token, gameId, playTimeSeconds);\n }\n\n async trackMatch(gameId: string, body: TrackMatchEndRequest): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.trackMatchEnd(token, gameId, body);\n }\n\n async emit(\n gameId: string,\n actionCode: GameEventKey | string,\n opts?: { value?: number; refId?: string; payload?: Record<string, unknown> }\n ): Promise<EmitGameEventResponse> {\n const token = await this.requireToken();\n const body: EmitGameEventRequest = {\n actionCode,\n value: opts?.value,\n refId: opts?.refId,\n payload: opts?.payload,\n };\n return this.raw.emitGameEvent(token, gameId, body);\n }\n\n async getMyProfile(): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getMyProfile(token);\n }\n\n async getMyBalance(): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getMyBalance(token);\n }\n\n async getBalances(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getBalances(token, query);\n }\n\n async getBalanceHistory(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.getBalanceHistory(token, query);\n }\n\n async listReferrals(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.listReferrals(token, query);\n }\n\n async setReferral(body: Record<string, any>): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.setReferral(token, body);\n }\n\n async listTasks(): Promise<any[]> {\n const token = await this.requireToken();\n return this.raw.listTasks(token);\n }\n\n async listFinishedTasks(): Promise<any[]> {\n const token = await this.requireToken();\n return this.raw.listFinishedTasks(token);\n }\n\n async startTask(body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.startTask(token, body);\n }\n\n async claimTask(body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimTask(token, body);\n }\n\n async getPlatformQuests(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getPlatformQuests(token, query);\n }\n\n async getCampaignQuests(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getCampaignQuests(token, query);\n }\n\n async claimQuest(questProgressId: string): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimQuest(token, questProgressId);\n }\n\n async claimMilestone(milestoneId: string, body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimMilestone(token, milestoneId, body);\n }\n}\n","import type { LooplayInitParams, LooplaySDKCreateOptions } from './types';\nimport { LooplayAuth } from './auth/looplay-auth';\nimport { ApiClient } from './apps/api-client';\nimport type { EmitGameEventResponse, GameEventKey } from './apps/LooplaySDK.types';\nimport { MissingAuthError, MissingBaseUrlError, NotInitializedError } from './errors';\n\nexport class LooplaySDK {\n readonly auth?: LooplayAuth;\n readonly api?: ApiClient;\n\n private gameId?: string;\n private initialized = false;\n\n constructor(options: LooplaySDKCreateOptions = {}) {\n const { auth, baseUrl, fetch, defaultHeaders } = options;\n\n if (auth) {\n this.auth = new LooplayAuth(auth);\n }\n\n if (baseUrl) {\n this.api = new ApiClient({\n baseUrl,\n fetch,\n defaultHeaders,\n getAccessToken: async () => this.auth?.getAccessToken(),\n });\n }\n }\n\n async init(params: LooplayInitParams): Promise<void> {\n this.gameId = params.gameId;\n await this.auth?.init();\n await this.verifyGameId(params);\n this.initialized = true;\n }\n\n async getAccessToken(): Promise<string | undefined> {\n return this.auth?.getAccessToken();\n }\n\n getGameId(): string | undefined {\n return this.gameId;\n }\n\n async getMyProfile(): Promise<any> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n return this.api.getMyProfile();\n }\n\n async trackPlay(playTimeSeconds?: number): Promise<boolean> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.trackPlay(this.gameId, playTimeSeconds);\n }\n\n /**\n * Report that a match/round ended.\n * Maps to PLAY_MATCH (and WIN_MATCH when isWin=true).\n * matchId is the idempotency anchor — safe to call twice with the same matchId.\n */\n async trackMatch(\n matchId: string,\n opts: { durationSeconds: number; isCompleted?: boolean; isWin?: boolean }\n ): Promise<boolean> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.trackMatch(this.gameId, {\n matchId,\n matchDurationSeconds: opts.durationSeconds,\n isCompleted: opts.isCompleted,\n isWin: opts.isWin,\n });\n }\n\n /**\n * Emit a custom action event (CUSTOM_ACTION metric).\n * Use GameEventKey for platform-defined codes; custom strings for game-specific quests.\n * Pass refId to make the call idempotent — same refId = same event, dedup-safe.\n */\n async emit(\n actionCode: GameEventKey | string,\n opts?: { value?: number; refId?: string; payload?: Record<string, unknown> }\n ): Promise<EmitGameEventResponse> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.emit(this.gameId, actionCode, opts);\n }\n\n private assertInitialized(): void {\n if (!this.initialized) throw new NotInitializedError();\n }\n\n private async verifyGameId(params: LooplayInitParams): Promise<void> {\n if ((params.verifyMode ?? 'none') === 'none') return;\n // strict: requires auth + calls GET /games/:id\n if (!this.auth) throw new MissingAuthError();\n if (!this.api) throw new MissingBaseUrlError();\n await this.api.getGameDetail(params.gameId);\n }\n}\n","import { LooplaySDKError } from '../../errors';\nimport { ServiceClient, type ServiceClientOptions } from '../../apps/service-client';\nimport type {\n AuthLoginParams,\n AuthLoginResult,\n AuthProvider,\n LooplaySession,\n LooplayUser\n} from '../types';\n\nexport interface TelegramAuthLoginParams extends AuthLoginParams {\n telegramInitData?: string;\n}\n\nexport interface TelegramAuthProviderOptions extends ServiceClientOptions {\n /**\n * Optional override for how to read Telegram init data.\n * If omitted, provider will try `params.telegramInitData` then `globalThis.Telegram.WebApp.initData`.\n */\n getTelegramInitData?: () => string | undefined;\n\n /**\n * Optional mapper from backend user payload to LooplayUser.\n * If omitted, provider will try common fields like id/_id/userId/telegramId.\n */\n mapUser?: (rawUser: Record<string, any>) => LooplayUser;\n}\n\nclass MissingTelegramInitDataError extends LooplaySDKError {\n constructor() {\n super('Missing Telegram init data');\n this.name = 'MissingTelegramInitDataError';\n }\n}\n\nclass MissingRefreshTokenError extends LooplaySDKError {\n constructor() {\n super('Missing refresh token');\n this.name = 'MissingRefreshTokenError';\n }\n}\n\nfunction decodeJwtExpMs(token: string | undefined): number | undefined {\n if (!token) return undefined;\n const parts = token.split('.');\n if (parts.length < 2) return undefined;\n\n try {\n const payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n const padded = payload + '==='.slice((payload.length + 3) % 4);\n if (typeof (globalThis as any).atob !== 'function') return undefined;\n\n const json = (globalThis as any).atob(padded) as string;\n const parsed = JSON.parse(json) as { exp?: number };\n if (typeof parsed.exp !== 'number') return undefined;\n return parsed.exp * 1000;\n } catch {\n return undefined;\n }\n}\n\nexport class TelegramAuthProvider implements AuthProvider {\n readonly id = 'telegram';\n\n private readonly client: ServiceClient;\n private readonly getTelegramInitData?: () => string | undefined;\n private readonly mapUser?: (rawUser: Record<string, any>) => LooplayUser;\n\n private session: LooplaySession | null = null;\n\n constructor(options: TelegramAuthProviderOptions) {\n this.client = new ServiceClient(options);\n this.getTelegramInitData = options.getTelegramInitData;\n this.mapUser = options.mapUser;\n }\n\n onSessionChanged = (session: LooplaySession | null): void => {\n this.session = session;\n };\n\n async login(params?: TelegramAuthLoginParams): Promise<AuthLoginResult> {\n const initData =\n params?.telegramInitData ??\n this.getTelegramInitData?.() ??\n (globalThis as any)?.Telegram?.WebApp?.initData;\n\n if (!initData) throw new MissingTelegramInitDataError();\n\n const result = await this.client.telegramLogin(initData);\n\n const rawUser = (result.user ?? {}) as Record<string, any>;\n const user = this.mapUser ? this.mapUser(rawUser) : this.defaultMapUser(rawUser);\n\n const session: LooplaySession = {\n user,\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: decodeJwtExpMs(result.accessToken)\n };\n\n this.session = session;\n return { session };\n }\n\n async refresh(): Promise<Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>> {\n const currentSession = this.session;\n const refreshToken = currentSession?.refreshToken;\n if (!currentSession || !refreshToken) throw new MissingRefreshTokenError();\n\n const result = await this.client.refresh(refreshToken);\n\n const next = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: decodeJwtExpMs(result.accessToken)\n } satisfies Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>;\n\n this.session = { ...currentSession, ...next };\n return next;\n }\n\n async logout(): Promise<void> {\n const refreshToken = this.session?.refreshToken;\n\n if (refreshToken) {\n try {\n await this.client.logout(refreshToken);\n } catch {\n // best-effort\n }\n }\n\n this.session = null;\n }\n\n private defaultMapUser(raw: Record<string, any>): LooplayUser {\n const id = raw.id ?? raw._id ?? raw.userId ?? raw.telegramId;\n if (id === undefined || id === null || String(id).trim() === '') {\n throw new LooplaySDKError('Missing user id from auth response');\n }\n\n return {\n id: String(id),\n displayName: raw.displayName ?? raw.username ?? raw.name,\n avatarUrl: raw.avatarUrl ?? raw.photoUrl ?? raw.avatar\n };\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var LooplaySDK=(function(exports){'use strict';var a=class extends Error{constructor(e){super(e),this.name="LooplaySDKError";}},l=class extends a{constructor(){super("LooplaySDK not initialized. Call init({ gameId }) first."),this.name="NotInitializedError";}},o=class extends a{constructor(){super("Missing baseUrl. Provide `baseUrl` to enable HTTP integration."),this.name="MissingBaseUrlError";}},m=class extends a{constructor(){super("Missing auth. Provide `auth` options to enable user login/session."),this.name="MissingAuthError";}},d=class extends a{constructor(){super("Not authenticated. Login is required for this operation."),this.name="NotAuthenticatedError";}};var g=class{map=new Map;async getItem(e){return this.map.has(e)?this.map.get(e):null}async setItem(e,t){this.map.set(e,t);}async removeItem(e){this.map.delete(e);}},R=class{async getItem(e){return typeof window>"u"||!window.localStorage?null:window.localStorage.getItem(e)}async setItem(e,t){typeof window>"u"||!window.localStorage||window.localStorage.setItem(e,t);}async removeItem(e){typeof window>"u"||!window.localStorage||window.localStorage.removeItem(e);}};var P=class extends a{constructor(){super("Invalid session returned by auth provider"),this.name="InvalidSessionError";}},p=class{provider;storage;key;session=null;listeners=new Set;constructor(e){this.provider=e.provider,this.storage=e.storage??new g,this.key=`${e.storageKeyPrefix??"looplay"}:auth:session`;}async init(){await this.provider.init?.(),await this.restoreFromStorage(),await this.provider.onSessionChanged?.(this.session);}getSession(){return this.session}async login(e){let t=await this.provider.login(e);if(!t?.session?.user?.id)throw new P;return await this.setSession(t.session,"login"),t.session}async logout(){await this.provider.logout(),await this.setSession(null,"logout");}async getAccessToken(){if(!this.session)return;let e=Date.now();if(!(typeof this.session.expiresAt=="number"&&this.session.expiresAt<=e))return this.session.accessToken;if(!this.provider.refresh)return this.session.accessToken;let s=await this.provider.refresh(),r={...this.session,...s};return await this.setSession(r,"sessionChanged"),r.accessToken}on(e,t){return this.listeners.add(t),()=>this.listeners.delete(t)}async restoreFromStorage(){let e=await this.storage.getItem(this.key);if(e)try{let t=JSON.parse(e);t?.user?.id&&(this.session=t);}catch{await this.storage.removeItem(this.key);}}async setSession(e,t){this.session=e,await this.provider.onSessionChanged?.(this.session),e?await this.storage.setItem(this.key,JSON.stringify(e)):await this.storage.removeItem(this.key);for(let s of this.listeners)s(this.session);}};var T=class extends Error{status;bodyText;constructor(e,t,s){super(e),this.name="HttpError",this.status=t,this.bodyText=s;}},y=class{baseUrl;fetchFn;defaultHeaders;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.fetchFn=e.fetch??fetch,this.defaultHeaders=e.defaultHeaders??{};}async request(e,t,s){let r=this.buildUrl(t,s?.query),i=this.mergeHeaders(this.defaultHeaders,s?.headers);s?.bearerToken&&(i.Authorization=`Bearer ${s.bearerToken}`);let c;s?.body!==void 0&&(i["Content-Type"]=i["Content-Type"]??"application/json",c=JSON.stringify(s.body));let u=await this.fetchFn(r,{method:e,headers:i,body:c});if(!u.ok){let q=await this.safeText(u);throw new T(`HTTP ${u.status} ${u.statusText}`,u.status,q)}let v=await this.safeText(u);if(v)return JSON.parse(v)}mergeHeaders(...e){let t={};for(let s of e)if(s)for(let[r,i]of Object.entries(s))i!==void 0&&(t[r]=i);return t}buildUrl(e,t){let s=e.startsWith("/")?e:`/${e}`,r=new URL(`${this.baseUrl}${s}`);if(t)for(let[i,c]of Object.entries(t))c!==void 0&&r.searchParams.set(i,String(c));return r.toString()}async safeText(e){try{return await e.text()}catch{return ""}}};var h=class{http;constructor(e){this.http=new y(e);}async telegramLogin(e){let t={telegramInitData:e};return this.http.request("POST","/account/telegram-login",{body:t})}async refresh(e){let t={refreshToken:e};return this.http.request("POST","/account/refresh",{body:t})}async logout(e){let t={refreshToken:e};return this.http.request("POST","/account/logout",{body:t})}async listGames(e){return this.http.request("GET","/games",{query:e})}async getGameDetail(e,t){return this.http.request("GET",`/games/${encodeURIComponent(e)}`,{bearerToken:t})}async listRecentPlayed(e,t){return this.http.request("GET","/games/recent-play",{bearerToken:e,query:t})}async trackPlay(e,t,s){let r={playTimeSeconds:s};return await this.http.request("POST",`/games/${encodeURIComponent(t)}/play`,{bearerToken:e,body:r}),true}async trackMatchEnd(e,t,s){return await this.http.request("POST",`/games/${encodeURIComponent(t)}/end`,{bearerToken:e,body:s}),true}async emitGameEvent(e,t,s){return this.http.request("POST",`/games/${encodeURIComponent(t)}/emit`,{bearerToken:e,body:s})}async getBalances(e,t){return this.http.request("GET","/balance",{bearerToken:e,query:t})}async getBalanceHistory(e,t){return this.http.request("GET","/balance/history",{bearerToken:e,query:t})}async getMyProfile(e){return this.http.request("GET","/user/profile",{bearerToken:e})}async getMyBalance(e){return this.http.request("GET","/user/balance",{bearerToken:e})}async listReferrals(e,t){return this.http.request("GET","/referrals",{bearerToken:e,query:t})}async setReferral(e,t){return this.http.request("POST","/referrals/set",{bearerToken:e,body:t})}async listTasks(e){return this.http.request("GET","/task",{bearerToken:e})}async listFinishedTasks(e){return this.http.request("GET","/task/finished",{bearerToken:e})}async startTask(e,t){return this.http.request("POST","/task/start",{bearerToken:e,body:t})}async claimTask(e,t){return this.http.request("POST","/task/claim",{bearerToken:e,body:t})}async getPlatformQuests(e,t){return this.http.request("GET","/quest/platform",{bearerToken:e,query:t})}async getCampaignQuests(e,t){return this.http.request("GET","/quest/campaign",{bearerToken:e,query:t})}async claimQuest(e,t){return this.http.request("POST",`/quest/${encodeURIComponent(t)}/claim`,{bearerToken:e})}async claimMilestone(e,t,s){return this.http.request("POST",`/quest/milestone/${encodeURIComponent(t)}/claim`,{bearerToken:e,body:s})}};var f=class{raw;getAccessToken;constructor(e){if(!e.baseUrl)throw new o;this.raw=new h({baseUrl:e.baseUrl,fetch:e.fetch,defaultHeaders:e.defaultHeaders}),this.getAccessToken=e.getAccessToken;}unsafeRaw(){return this.raw}async listGames(e){return this.raw.listGames(e)}async requireToken(){let e=await this.getAccessToken?.();if(!e)throw new d;return e}async getGameDetail(e){let t=await this.requireToken();return this.raw.getGameDetail(e,t)}async listRecentPlayed(e){let t=await this.requireToken();return this.raw.listRecentPlayed(t,e)}async trackPlay(e,t){let s=await this.requireToken();return this.raw.trackPlay(s,e,t)}async trackMatch(e,t){let s=await this.requireToken();return this.raw.trackMatchEnd(s,e,t)}async emit(e,t,s){let r=await this.requireToken(),i={actionCode:t,value:s?.value,refId:s?.refId,payload:s?.payload};return this.raw.emitGameEvent(r,e,i)}async getMyProfile(){let e=await this.requireToken();return this.raw.getMyProfile(e)}async getMyBalance(){let e=await this.requireToken();return this.raw.getMyBalance(e)}async getBalances(e){let t=await this.requireToken();return this.raw.getBalances(t,e)}async getBalanceHistory(e){let t=await this.requireToken();return this.raw.getBalanceHistory(t,e)}async listReferrals(e){let t=await this.requireToken();return this.raw.listReferrals(t,e)}async setReferral(e){let t=await this.requireToken();return this.raw.setReferral(t,e)}async listTasks(){let e=await this.requireToken();return this.raw.listTasks(e)}async listFinishedTasks(){let e=await this.requireToken();return this.raw.listFinishedTasks(e)}async startTask(e){let t=await this.requireToken();return this.raw.startTask(t,e)}async claimTask(e){let t=await this.requireToken();return this.raw.claimTask(t,e)}async getPlatformQuests(e){let t=await this.requireToken();return this.raw.getPlatformQuests(t,e)}async getCampaignQuests(e){let t=await this.requireToken();return this.raw.getCampaignQuests(t,e)}async claimQuest(e){let t=await this.requireToken();return this.raw.claimQuest(t,e)}async claimMilestone(e,t){let s=await this.requireToken();return this.raw.claimMilestone(s,e,t)}};var S=class{auth;api;gameId;initialized=false;constructor(e={}){let{auth:t,baseUrl:s,fetch:r,defaultHeaders:i}=e;t&&(this.auth=new p(t)),s&&(this.api=new f({baseUrl:s,fetch:r,defaultHeaders:i,getAccessToken:async()=>this.auth?.getAccessToken()}));}async init(e){this.gameId=e.gameId,await this.auth?.init(),await this.verifyGameId(e),this.initialized=true;}async getAccessToken(){return this.auth?.getAccessToken()}getGameId(){return this.gameId}async getMyProfile(){if(this.assertInitialized(),!this.api)throw new o;return this.api.getMyProfile()}async trackPlay(e){if(this.assertInitialized(),!this.api)throw new o;if(!this.gameId)throw new l;return this.api.trackPlay(this.gameId,e)}async trackMatch(e,t){if(this.assertInitialized(),!this.api)throw new o;if(!this.gameId)throw new l;return this.api.trackMatch(this.gameId,{matchId:e,matchDurationSeconds:t.durationSeconds,isCompleted:t.isCompleted,isWin:t.isWin})}async emit(e,t){if(this.assertInitialized(),!this.api)throw new o;if(!this.gameId)throw new l;return this.api.emit(this.gameId,e,t)}assertInitialized(){if(!this.initialized)throw new l}async verifyGameId(e){if((e.verifyMode??"none")!=="none"){if(!this.auth)throw new m;if(!this.api)throw new o;await this.api.getGameDetail(e.gameId);}}};var w=class extends a{constructor(){super("Missing Telegram init data"),this.name="MissingTelegramInitDataError";}},k=class extends a{constructor(){super("Missing refresh token"),this.name="MissingRefreshTokenError";}};function b(n){if(!n)return;let e=n.split(".");if(!(e.length<2))try{let t=e[1].replace(/-/g,"+").replace(/_/g,"/"),s=t+"===".slice((t.length+3)%4);if(typeof globalThis.atob!="function")return;let r=globalThis.atob(s),i=JSON.parse(r);return typeof i.exp!="number"?void 0:i.exp*1e3}catch{return}}var x=class{id="telegram";client;getTelegramInitData;mapUser;session=null;constructor(e){this.client=new h(e),this.getTelegramInitData=e.getTelegramInitData,this.mapUser=e.mapUser;}onSessionChanged=e=>{this.session=e;};async login(e){let t=e?.telegramInitData??this.getTelegramInitData?.()??globalThis?.Telegram?.WebApp?.initData;if(!t)throw new w;let s=await this.client.telegramLogin(t),r=s.user??{},c={user:this.mapUser?this.mapUser(r):this.defaultMapUser(r),accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:b(s.accessToken)};return this.session=c,{session:c}}async refresh(){let e=this.session,t=e?.refreshToken;if(!e||!t)throw new k;let s=await this.client.refresh(t),r={accessToken:s.accessToken,refreshToken:s.refreshToken,expiresAt:b(s.accessToken)};return this.session={...e,...r},r}async logout(){let e=this.session?.refreshToken;if(e)try{await this.client.logout(e);}catch{}this.session=null;}defaultMapUser(e){let t=e.id??e._id??e.userId??e.telegramId;if(t==null||String(t).trim()==="")throw new a("Missing user id from auth response");return {id:String(t),displayName:e.displayName??e.username??e.name,avatarUrl:e.avatarUrl??e.photoUrl??e.avatar}}};exports.ApiClient=f;exports.BrowserLocalStorageAuthStorage=R;exports.HttpClient=y;exports.HttpError=T;exports.LooplayAuth=p;exports.LooplaySDK=S;exports.LooplaySDKError=a;exports.MemoryAuthStorage=g;exports.MissingAuthError=m;exports.MissingBaseUrlError=o;exports.NotAuthenticatedError=d;exports.NotInitializedError=l;exports.ServiceClient=h;exports.TelegramAuthProvider=x;return exports;})({});//# sourceMappingURL=looplay-sdk.min.js.map
2
+ //# sourceMappingURL=looplay-sdk.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/auth/storage.ts","../src/auth/looplay-auth.ts","../src/apps/http.ts","../src/apps/service-client.ts","../src/apps/api-client.ts","../src/looplay-sdk.ts","../src/auth/providers/telegram-auth-provider.ts"],"names":["LooplaySDKError","message","NotInitializedError","MissingBaseUrlError","MissingAuthError","NotAuthenticatedError","MemoryAuthStorage","key","value","BrowserLocalStorageAuthStorage","InvalidSessionError","LooplayAuth","options","params","result","now","refreshed","next","eventName","listener","raw","parsed","event","HttpError","status","bodyText","HttpClient","method","path","url","headers","body","res","text","sources","src","query","normalizedPath","ServiceClient","telegramInitData","refreshToken","gameId","bearerToken","playTimeSeconds","questProgressId","milestoneId","ApiClient","token","actionCode","opts","LooplaySDK","auth","baseUrl","fetch","defaultHeaders","matchId","MissingTelegramInitDataError","MissingRefreshTokenError","decodeJwtExpMs","parts","payload","padded","json","TelegramAuthProvider","session","initData","rawUser","currentSession","id"],"mappings":"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","file":"looplay-sdk.min.js","sourcesContent":["export class LooplaySDKError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = 'LooplaySDKError';\n }\n}\n\nexport class NotInitializedError extends LooplaySDKError {\n constructor() {\n super('LooplaySDK not initialized. Call init({ gameId }) first.');\n this.name = 'NotInitializedError';\n }\n}\n\nexport class MissingBaseUrlError extends LooplaySDKError {\n constructor() {\n super('Missing baseUrl. Provide `baseUrl` to enable HTTP integration.');\n this.name = 'MissingBaseUrlError';\n }\n}\n\nexport class MissingAuthError extends LooplaySDKError {\n constructor() {\n super('Missing auth. Provide `auth` options to enable user login/session.');\n this.name = 'MissingAuthError';\n }\n}\n\nexport class NotAuthenticatedError extends LooplaySDKError {\n constructor() {\n super('Not authenticated. Login is required for this operation.');\n this.name = 'NotAuthenticatedError';\n }\n}\n","import type { AuthStorage } from './types';\n\nexport class MemoryAuthStorage implements AuthStorage {\n private readonly map = new Map<string, string>();\n\n async getItem(key: string): Promise<string | null> {\n return this.map.has(key) ? (this.map.get(key) as string) : null;\n }\n\n async setItem(key: string, value: string): Promise<void> {\n this.map.set(key, value);\n }\n\n async removeItem(key: string): Promise<void> {\n this.map.delete(key);\n }\n}\n\nexport class BrowserLocalStorageAuthStorage implements AuthStorage {\n async getItem(key: string): Promise<string | null> {\n if (typeof window === 'undefined' || !window.localStorage) return null;\n return window.localStorage.getItem(key);\n }\n\n async setItem(key: string, value: string): Promise<void> {\n if (typeof window === 'undefined' || !window.localStorage) return;\n window.localStorage.setItem(key, value);\n }\n\n async removeItem(key: string): Promise<void> {\n if (typeof window === 'undefined' || !window.localStorage) return;\n window.localStorage.removeItem(key);\n }\n}\n","import { LooplaySDKError } from '../errors';\nimport {\n type AuthEventName,\n type AuthLoginParams,\n type AuthProvider,\n type AuthStorage,\n type LooplayAuthOptions,\n type LooplaySession\n} from './types';\nimport { MemoryAuthStorage } from './storage';\n\nclass InvalidSessionError extends LooplaySDKError {\n constructor() {\n super('Invalid session returned by auth provider');\n this.name = 'InvalidSessionError';\n }\n}\n\ntype Listener = (session: LooplaySession | null) => void;\n\nexport class LooplayAuth {\n private readonly provider: AuthProvider;\n private readonly storage: AuthStorage;\n private readonly key: string;\n\n private session: LooplaySession | null = null;\n private readonly listeners = new Set<Listener>();\n\n constructor(options: LooplayAuthOptions) {\n this.provider = options.provider;\n this.storage = options.storage ?? new MemoryAuthStorage();\n this.key = `${options.storageKeyPrefix ?? 'looplay'}:auth:session`;\n }\n\n async init(): Promise<void> {\n await this.provider.init?.();\n await this.restoreFromStorage();\n\n // Keep provider in sync with restored session (if any).\n await this.provider.onSessionChanged?.(this.session);\n }\n\n getSession(): LooplaySession | null {\n return this.session;\n }\n\n async login(params?: AuthLoginParams): Promise<LooplaySession> {\n const result = await this.provider.login(params);\n\n if (!result?.session?.user?.id) {\n throw new InvalidSessionError();\n }\n\n await this.setSession(result.session, 'login');\n return result.session;\n }\n\n async logout(): Promise<void> {\n await this.provider.logout();\n await this.setSession(null, 'logout');\n }\n\n async getAccessToken(): Promise<string | undefined> {\n if (!this.session) return undefined;\n\n const now = Date.now();\n const isExpired =\n typeof this.session.expiresAt === 'number' && this.session.expiresAt <= now;\n\n if (!isExpired) return this.session.accessToken;\n\n if (!this.provider.refresh) return this.session.accessToken;\n\n const refreshed = await this.provider.refresh();\n const next = { ...this.session, ...refreshed };\n await this.setSession(next, 'sessionChanged');\n\n return next.accessToken;\n }\n\n on(eventName: AuthEventName, listener: Listener): () => void {\n // eventName reserved for future filtering; for now notify on any change\n void eventName;\n\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private async restoreFromStorage(): Promise<void> {\n const raw = await this.storage.getItem(this.key);\n if (!raw) return;\n\n try {\n const parsed = JSON.parse(raw) as LooplaySession;\n if (parsed?.user?.id) {\n this.session = parsed;\n }\n } catch {\n // ignore corrupted cache\n await this.storage.removeItem(this.key);\n }\n }\n\n private async setSession(next: LooplaySession | null, event: AuthEventName): Promise<void> {\n this.session = next;\n\n await this.provider.onSessionChanged?.(this.session);\n\n if (next) {\n await this.storage.setItem(this.key, JSON.stringify(next));\n } else {\n await this.storage.removeItem(this.key);\n }\n\n for (const listener of this.listeners) {\n listener(this.session);\n }\n\n // reserved for future event-specific hooks\n void event;\n }\n}\n","export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchLike;\n defaultHeaders?: Record<string, string>;\n}\n\nexport class HttpError extends Error {\n readonly status: number;\n readonly bodyText?: string;\n\n constructor(message: string, status: number, bodyText?: string) {\n super(message);\n this.name = 'HttpError';\n this.status = status;\n this.bodyText = bodyText;\n }\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly fetchFn: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '');\n this.fetchFn = options.fetch ?? fetch;\n this.defaultHeaders = options.defaultHeaders ?? {};\n }\n\n async request<T>(\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE',\n path: string,\n options?: {\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string | undefined>;\n bearerToken?: string;\n body?: unknown;\n }\n ): Promise<T> {\n const url = this.buildUrl(path, options?.query);\n\n const headers: Record<string, string> = this.mergeHeaders(\n this.defaultHeaders,\n options?.headers\n );\n\n if (options?.bearerToken) {\n headers.Authorization = `Bearer ${options.bearerToken}`;\n }\n\n let body: BodyInit | undefined;\n if (options?.body !== undefined) {\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json';\n body = JSON.stringify(options.body);\n }\n\n const res = await this.fetchFn(url, { method, headers, body });\n\n if (!res.ok) {\n const text = await this.safeText(res);\n throw new HttpError(`HTTP ${res.status} ${res.statusText}`, res.status, text);\n }\n\n // Some endpoints may return empty body.\n const text = await this.safeText(res);\n if (!text) return undefined as T;\n\n return JSON.parse(text) as T;\n }\n\n private mergeHeaders(\n ...sources: Array<Record<string, string | undefined> | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const src of sources) {\n if (!src) continue;\n for (const [key, value] of Object.entries(src)) {\n if (value === undefined) continue;\n result[key] = value;\n }\n }\n\n return result;\n }\n\n private buildUrl(\n path: string,\n query?: Record<string, string | number | boolean | undefined>\n ): string {\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${this.baseUrl}${normalizedPath}`);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) continue;\n url.searchParams.set(key, String(value));\n }\n }\n\n return url.toString();\n }\n\n private async safeText(res: Response): Promise<string> {\n try {\n return await res.text();\n } catch {\n return '';\n }\n }\n}\n","import { HttpClient, type HttpClientOptions } from './http';\nimport type {\n AuthResultDto,\n EmitGameEventRequest,\n EmitGameEventResponse,\n PagingResponse,\n RefreshTokenRequest,\n TelegramLoginRequest,\n TrackGamePlayRequest,\n TrackMatchEndRequest,\n} from './LooplaySDK.types';\n\nexport interface ServiceClientOptions extends HttpClientOptions {}\n\n/**\n * Low-level HTTP client that maps 1:1 to backend routes.\n * Methods requiring user auth accept `bearerToken` explicitly.\n */\nexport class ServiceClient {\n private readonly http: HttpClient;\n\n constructor(options: ServiceClientOptions) {\n this.http = new HttpClient(options);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Auth\n // ─────────────────────────────────────────────────────────────────────────────\n\n async telegramLogin(telegramInitData: string): Promise<AuthResultDto> {\n const body: TelegramLoginRequest = { telegramInitData };\n return this.http.request('POST', '/account/telegram-login', { body });\n }\n\n async refresh(refreshToken: string): Promise<AuthResultDto> {\n const body: RefreshTokenRequest = { refreshToken };\n return this.http.request('POST', '/account/refresh', { body });\n }\n\n async logout(refreshToken: string): Promise<boolean> {\n const body: RefreshTokenRequest = { refreshToken };\n return this.http.request('POST', '/account/logout', { body });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Games\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listGames(query?: Record<string, any>): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/games', { query });\n }\n\n async getGameDetail(gameId: string, bearerToken: string): Promise<any> {\n return this.http.request('GET', `/games/${encodeURIComponent(gameId)}`, {\n bearerToken,\n });\n }\n\n async listRecentPlayed(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/games/recent-play', { bearerToken, query });\n }\n\n async trackPlay(\n bearerToken: string,\n gameId: string,\n playTimeSeconds?: number\n ): Promise<boolean> {\n const body: TrackGamePlayRequest = { playTimeSeconds };\n await this.http.request('POST', `/games/${encodeURIComponent(gameId)}/play`, {\n bearerToken,\n body,\n });\n return true;\n }\n\n async trackMatchEnd(\n bearerToken: string,\n gameId: string,\n body: TrackMatchEndRequest\n ): Promise<boolean> {\n await this.http.request('POST', `/games/${encodeURIComponent(gameId)}/end`, {\n bearerToken,\n body,\n });\n return true;\n }\n\n async emitGameEvent(\n bearerToken: string,\n gameId: string,\n body: EmitGameEventRequest\n ): Promise<EmitGameEventResponse> {\n return this.http.request('POST', `/games/${encodeURIComponent(gameId)}/emit`, {\n bearerToken,\n body,\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Balance\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getBalances(bearerToken: string, query?: Record<string, any>): Promise<any> {\n return this.http.request('GET', '/balance', { bearerToken, query });\n }\n\n async getBalanceHistory(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/balance/history', { bearerToken, query });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // User\n // ─────────────────────────────────────────────────────────────────────────────\n\n async getMyProfile(bearerToken: string): Promise<any> {\n return this.http.request('GET', '/user/profile', { bearerToken });\n }\n\n async getMyBalance(bearerToken: string): Promise<any> {\n return this.http.request('GET', '/user/balance', { bearerToken });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Referrals\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listReferrals(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<PagingResponse<any>> {\n return this.http.request('GET', '/referrals', { bearerToken, query });\n }\n\n async setReferral(bearerToken: string, body: Record<string, any>): Promise<boolean> {\n return this.http.request('POST', '/referrals/set', { bearerToken, body });\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tasks / Quests\n // ─────────────────────────────────────────────────────────────────────────────\n\n async listTasks(bearerToken: string): Promise<any[]> {\n return this.http.request('GET', '/task', { bearerToken });\n }\n\n async listFinishedTasks(bearerToken: string): Promise<any[]> {\n return this.http.request('GET', '/task/finished', { bearerToken });\n }\n\n async startTask(bearerToken: string, body: Record<string, any>): Promise<any> {\n return this.http.request('POST', '/task/start', { bearerToken, body });\n }\n\n async claimTask(bearerToken: string, body: Record<string, any>): Promise<any> {\n return this.http.request('POST', '/task/claim', { bearerToken, body });\n }\n\n async getPlatformQuests(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<any> {\n return this.http.request('GET', '/quest/platform', { bearerToken, query });\n }\n\n async getCampaignQuests(\n bearerToken: string,\n query?: Record<string, any>\n ): Promise<any> {\n return this.http.request('GET', '/quest/campaign', { bearerToken, query });\n }\n\n async claimQuest(bearerToken: string, questProgressId: string): Promise<any> {\n return this.http.request('POST', `/quest/${encodeURIComponent(questProgressId)}/claim`, {\n bearerToken,\n });\n }\n\n async claimMilestone(\n bearerToken: string,\n milestoneId: string,\n body: Record<string, any>\n ): Promise<any> {\n return this.http.request(\n 'POST',\n `/quest/milestone/${encodeURIComponent(milestoneId)}/claim`,\n {\n bearerToken,\n body,\n }\n );\n }\n}\n","import { MissingBaseUrlError, NotAuthenticatedError } from '../errors';\nimport type {\n EmitGameEventRequest,\n EmitGameEventResponse,\n GameEventKey,\n PagingResponse,\n TrackMatchEndRequest,\n} from './LooplaySDK.types';\nimport { ServiceClient } from './service-client';\nimport type { ServiceClientOptions } from './service-client';\n\nexport interface ApiClientOptions extends Omit<ServiceClientOptions, 'baseUrl'> {\n baseUrl?: string;\n getAccessToken?: () => Promise<string | undefined>;\n}\n\n/**\n * High-level API client that injects user auth automatically.\n */\nexport class ApiClient {\n private readonly raw: ServiceClient;\n private readonly getAccessToken?: () => Promise<string | undefined>;\n\n constructor(options: ApiClientOptions) {\n if (!options.baseUrl) throw new MissingBaseUrlError();\n\n this.raw = new ServiceClient({\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n defaultHeaders: options.defaultHeaders,\n });\n\n this.getAccessToken = options.getAccessToken;\n }\n\n /** Expose the underlying route-level client (requires manual bearerToken passing). */\n unsafeRaw(): ServiceClient {\n return this.raw;\n }\n\n // Public endpoints\n async listGames(query?: Record<string, any>): Promise<PagingResponse<any>> {\n return this.raw.listGames(query);\n }\n\n // Authenticated endpoints\n private async requireToken(): Promise<string> {\n const token = await this.getAccessToken?.();\n if (!token) throw new NotAuthenticatedError();\n return token;\n }\n\n async getGameDetail(gameId: string): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getGameDetail(gameId, token);\n }\n\n async listRecentPlayed(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.listRecentPlayed(token, query);\n }\n\n async trackPlay(gameId: string, playTimeSeconds?: number): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.trackPlay(token, gameId, playTimeSeconds);\n }\n\n async trackMatch(gameId: string, body: TrackMatchEndRequest): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.trackMatchEnd(token, gameId, body);\n }\n\n async emit(\n gameId: string,\n actionCode: GameEventKey | string,\n opts?: { value?: number; refId?: string; payload?: Record<string, unknown> }\n ): Promise<EmitGameEventResponse> {\n const token = await this.requireToken();\n const body: EmitGameEventRequest = {\n actionCode,\n value: opts?.value,\n refId: opts?.refId,\n payload: opts?.payload,\n };\n return this.raw.emitGameEvent(token, gameId, body);\n }\n\n async getMyProfile(): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getMyProfile(token);\n }\n\n async getMyBalance(): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getMyBalance(token);\n }\n\n async getBalances(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getBalances(token, query);\n }\n\n async getBalanceHistory(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.getBalanceHistory(token, query);\n }\n\n async listReferrals(query?: Record<string, any>): Promise<PagingResponse<any>> {\n const token = await this.requireToken();\n return this.raw.listReferrals(token, query);\n }\n\n async setReferral(body: Record<string, any>): Promise<boolean> {\n const token = await this.requireToken();\n return this.raw.setReferral(token, body);\n }\n\n async listTasks(): Promise<any[]> {\n const token = await this.requireToken();\n return this.raw.listTasks(token);\n }\n\n async listFinishedTasks(): Promise<any[]> {\n const token = await this.requireToken();\n return this.raw.listFinishedTasks(token);\n }\n\n async startTask(body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.startTask(token, body);\n }\n\n async claimTask(body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimTask(token, body);\n }\n\n async getPlatformQuests(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getPlatformQuests(token, query);\n }\n\n async getCampaignQuests(query?: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.getCampaignQuests(token, query);\n }\n\n async claimQuest(questProgressId: string): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimQuest(token, questProgressId);\n }\n\n async claimMilestone(milestoneId: string, body: Record<string, any>): Promise<any> {\n const token = await this.requireToken();\n return this.raw.claimMilestone(token, milestoneId, body);\n }\n}\n","import type { LooplayInitParams, LooplaySDKCreateOptions } from './types';\nimport { LooplayAuth } from './auth/looplay-auth';\nimport { ApiClient } from './apps/api-client';\nimport type { EmitGameEventResponse, GameEventKey } from './apps/LooplaySDK.types';\nimport { MissingAuthError, MissingBaseUrlError, NotInitializedError } from './errors';\n\nexport class LooplaySDK {\n readonly auth?: LooplayAuth;\n readonly api?: ApiClient;\n\n private gameId?: string;\n private initialized = false;\n\n constructor(options: LooplaySDKCreateOptions = {}) {\n const { auth, baseUrl, fetch, defaultHeaders } = options;\n\n if (auth) {\n this.auth = new LooplayAuth(auth);\n }\n\n if (baseUrl) {\n this.api = new ApiClient({\n baseUrl,\n fetch,\n defaultHeaders,\n getAccessToken: async () => this.auth?.getAccessToken(),\n });\n }\n }\n\n async init(params: LooplayInitParams): Promise<void> {\n this.gameId = params.gameId;\n await this.auth?.init();\n await this.verifyGameId(params);\n this.initialized = true;\n }\n\n async getAccessToken(): Promise<string | undefined> {\n return this.auth?.getAccessToken();\n }\n\n getGameId(): string | undefined {\n return this.gameId;\n }\n\n async getMyProfile(): Promise<any> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n return this.api.getMyProfile();\n }\n\n async trackPlay(playTimeSeconds?: number): Promise<boolean> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.trackPlay(this.gameId, playTimeSeconds);\n }\n\n /**\n * Report that a match/round ended.\n * Maps to PLAY_MATCH (and WIN_MATCH when isWin=true).\n * matchId is the idempotency anchor — safe to call twice with the same matchId.\n */\n async trackMatch(\n matchId: string,\n opts: { durationSeconds: number; isCompleted?: boolean; isWin?: boolean }\n ): Promise<boolean> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.trackMatch(this.gameId, {\n matchId,\n matchDurationSeconds: opts.durationSeconds,\n isCompleted: opts.isCompleted,\n isWin: opts.isWin,\n });\n }\n\n /**\n * Emit a custom action event (CUSTOM_ACTION metric).\n * Use GameEventKey for platform-defined codes; custom strings for game-specific quests.\n * Pass refId to make the call idempotent — same refId = same event, dedup-safe.\n */\n async emit(\n actionCode: GameEventKey | string,\n opts?: { value?: number; refId?: string; payload?: Record<string, unknown> }\n ): Promise<EmitGameEventResponse> {\n this.assertInitialized();\n if (!this.api) throw new MissingBaseUrlError();\n if (!this.gameId) throw new NotInitializedError();\n return this.api.emit(this.gameId, actionCode, opts);\n }\n\n private assertInitialized(): void {\n if (!this.initialized) throw new NotInitializedError();\n }\n\n private async verifyGameId(params: LooplayInitParams): Promise<void> {\n if ((params.verifyMode ?? 'none') === 'none') return;\n // strict: requires auth + calls GET /games/:id\n if (!this.auth) throw new MissingAuthError();\n if (!this.api) throw new MissingBaseUrlError();\n await this.api.getGameDetail(params.gameId);\n }\n}\n","import { LooplaySDKError } from '../../errors';\nimport { ServiceClient, type ServiceClientOptions } from '../../apps/service-client';\nimport type {\n AuthLoginParams,\n AuthLoginResult,\n AuthProvider,\n LooplaySession,\n LooplayUser\n} from '../types';\n\nexport interface TelegramAuthLoginParams extends AuthLoginParams {\n telegramInitData?: string;\n}\n\nexport interface TelegramAuthProviderOptions extends ServiceClientOptions {\n /**\n * Optional override for how to read Telegram init data.\n * If omitted, provider will try `params.telegramInitData` then `globalThis.Telegram.WebApp.initData`.\n */\n getTelegramInitData?: () => string | undefined;\n\n /**\n * Optional mapper from backend user payload to LooplayUser.\n * If omitted, provider will try common fields like id/_id/userId/telegramId.\n */\n mapUser?: (rawUser: Record<string, any>) => LooplayUser;\n}\n\nclass MissingTelegramInitDataError extends LooplaySDKError {\n constructor() {\n super('Missing Telegram init data');\n this.name = 'MissingTelegramInitDataError';\n }\n}\n\nclass MissingRefreshTokenError extends LooplaySDKError {\n constructor() {\n super('Missing refresh token');\n this.name = 'MissingRefreshTokenError';\n }\n}\n\nfunction decodeJwtExpMs(token: string | undefined): number | undefined {\n if (!token) return undefined;\n const parts = token.split('.');\n if (parts.length < 2) return undefined;\n\n try {\n const payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n const padded = payload + '==='.slice((payload.length + 3) % 4);\n if (typeof (globalThis as any).atob !== 'function') return undefined;\n\n const json = (globalThis as any).atob(padded) as string;\n const parsed = JSON.parse(json) as { exp?: number };\n if (typeof parsed.exp !== 'number') return undefined;\n return parsed.exp * 1000;\n } catch {\n return undefined;\n }\n}\n\nexport class TelegramAuthProvider implements AuthProvider {\n readonly id = 'telegram';\n\n private readonly client: ServiceClient;\n private readonly getTelegramInitData?: () => string | undefined;\n private readonly mapUser?: (rawUser: Record<string, any>) => LooplayUser;\n\n private session: LooplaySession | null = null;\n\n constructor(options: TelegramAuthProviderOptions) {\n this.client = new ServiceClient(options);\n this.getTelegramInitData = options.getTelegramInitData;\n this.mapUser = options.mapUser;\n }\n\n onSessionChanged = (session: LooplaySession | null): void => {\n this.session = session;\n };\n\n async login(params?: TelegramAuthLoginParams): Promise<AuthLoginResult> {\n const initData =\n params?.telegramInitData ??\n this.getTelegramInitData?.() ??\n (globalThis as any)?.Telegram?.WebApp?.initData;\n\n if (!initData) throw new MissingTelegramInitDataError();\n\n const result = await this.client.telegramLogin(initData);\n\n const rawUser = (result.user ?? {}) as Record<string, any>;\n const user = this.mapUser ? this.mapUser(rawUser) : this.defaultMapUser(rawUser);\n\n const session: LooplaySession = {\n user,\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: decodeJwtExpMs(result.accessToken)\n };\n\n this.session = session;\n return { session };\n }\n\n async refresh(): Promise<Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>> {\n const currentSession = this.session;\n const refreshToken = currentSession?.refreshToken;\n if (!currentSession || !refreshToken) throw new MissingRefreshTokenError();\n\n const result = await this.client.refresh(refreshToken);\n\n const next = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: decodeJwtExpMs(result.accessToken)\n } satisfies Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>;\n\n this.session = { ...currentSession, ...next };\n return next;\n }\n\n async logout(): Promise<void> {\n const refreshToken = this.session?.refreshToken;\n\n if (refreshToken) {\n try {\n await this.client.logout(refreshToken);\n } catch {\n // best-effort\n }\n }\n\n this.session = null;\n }\n\n private defaultMapUser(raw: Record<string, any>): LooplayUser {\n const id = raw.id ?? raw._id ?? raw.userId ?? raw.telegramId;\n if (id === undefined || id === null || String(id).trim() === '') {\n throw new LooplaySDKError('Missing user id from auth response');\n }\n\n return {\n id: String(id),\n displayName: raw.displayName ?? raw.username ?? raw.name,\n avatarUrl: raw.avatarUrl ?? raw.photoUrl ?? raw.avatar\n };\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ export type { GameEventKey, TrackMatchEndRequest, EmitGameEventRequest, EmitGameEventResponse } from '@looplay/types';
2
+ export interface AuthResultDto {
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ user: Record<string, any>;
6
+ }
7
+ export interface TelegramLoginRequest {
8
+ telegramInitData: string;
9
+ }
10
+ export interface RefreshTokenRequest {
11
+ refreshToken: string;
12
+ }
13
+ export interface TrackGamePlayRequest {
14
+ playTimeSeconds?: number;
15
+ }
16
+ export interface PagingResponse<T> {
17
+ items: T[];
18
+ total: number;
19
+ page: number;
20
+ limit: number;
21
+ }
@@ -0,0 +1,42 @@
1
+ import type { EmitGameEventResponse, GameEventKey, PagingResponse, TrackMatchEndRequest } from './LooplaySDK.types';
2
+ import { ServiceClient } from './service-client';
3
+ import type { ServiceClientOptions } from './service-client';
4
+ export interface ApiClientOptions extends Omit<ServiceClientOptions, 'baseUrl'> {
5
+ baseUrl?: string;
6
+ getAccessToken?: () => Promise<string | undefined>;
7
+ }
8
+ /**
9
+ * High-level API client that injects user auth automatically.
10
+ */
11
+ export declare class ApiClient {
12
+ private readonly raw;
13
+ private readonly getAccessToken?;
14
+ constructor(options: ApiClientOptions);
15
+ /** Expose the underlying route-level client (requires manual bearerToken passing). */
16
+ unsafeRaw(): ServiceClient;
17
+ listGames(query?: Record<string, any>): Promise<PagingResponse<any>>;
18
+ private requireToken;
19
+ getGameDetail(gameId: string): Promise<any>;
20
+ listRecentPlayed(query?: Record<string, any>): Promise<PagingResponse<any>>;
21
+ trackPlay(gameId: string, playTimeSeconds?: number): Promise<boolean>;
22
+ trackMatch(gameId: string, body: TrackMatchEndRequest): Promise<boolean>;
23
+ emit(gameId: string, actionCode: GameEventKey | string, opts?: {
24
+ value?: number;
25
+ refId?: string;
26
+ payload?: Record<string, unknown>;
27
+ }): Promise<EmitGameEventResponse>;
28
+ getMyProfile(): Promise<any>;
29
+ getMyBalance(): Promise<any>;
30
+ getBalances(query?: Record<string, any>): Promise<any>;
31
+ getBalanceHistory(query?: Record<string, any>): Promise<PagingResponse<any>>;
32
+ listReferrals(query?: Record<string, any>): Promise<PagingResponse<any>>;
33
+ setReferral(body: Record<string, any>): Promise<boolean>;
34
+ listTasks(): Promise<any[]>;
35
+ listFinishedTasks(): Promise<any[]>;
36
+ startTask(body: Record<string, any>): Promise<any>;
37
+ claimTask(body: Record<string, any>): Promise<any>;
38
+ getPlatformQuests(query?: Record<string, any>): Promise<any>;
39
+ getCampaignQuests(query?: Record<string, any>): Promise<any>;
40
+ claimQuest(questProgressId: string): Promise<any>;
41
+ claimMilestone(milestoneId: string, body: Record<string, any>): Promise<any>;
42
+ }
@@ -0,0 +1,26 @@
1
+ export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
2
+ export interface HttpClientOptions {
3
+ baseUrl: string;
4
+ fetch?: FetchLike;
5
+ defaultHeaders?: Record<string, string>;
6
+ }
7
+ export declare class HttpError extends Error {
8
+ readonly status: number;
9
+ readonly bodyText?: string;
10
+ constructor(message: string, status: number, bodyText?: string);
11
+ }
12
+ export declare class HttpClient {
13
+ private readonly baseUrl;
14
+ private readonly fetchFn;
15
+ private readonly defaultHeaders;
16
+ constructor(options: HttpClientOptions);
17
+ request<T>(method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', path: string, options?: {
18
+ query?: Record<string, string | number | boolean | undefined>;
19
+ headers?: Record<string, string | undefined>;
20
+ bearerToken?: string;
21
+ body?: unknown;
22
+ }): Promise<T>;
23
+ private mergeHeaders;
24
+ private buildUrl;
25
+ private safeText;
26
+ }
@@ -0,0 +1,4 @@
1
+ export * from './http';
2
+ export * from './LooplaySDK.types';
3
+ export * from './service-client';
4
+ export * from './api-client';
@@ -0,0 +1,35 @@
1
+ import { type HttpClientOptions } from './http';
2
+ import type { AuthResultDto, EmitGameEventRequest, EmitGameEventResponse, PagingResponse, TrackMatchEndRequest } from './LooplaySDK.types';
3
+ export interface ServiceClientOptions extends HttpClientOptions {
4
+ }
5
+ /**
6
+ * Low-level HTTP client that maps 1:1 to backend routes.
7
+ * Methods requiring user auth accept `bearerToken` explicitly.
8
+ */
9
+ export declare class ServiceClient {
10
+ private readonly http;
11
+ constructor(options: ServiceClientOptions);
12
+ telegramLogin(telegramInitData: string): Promise<AuthResultDto>;
13
+ refresh(refreshToken: string): Promise<AuthResultDto>;
14
+ logout(refreshToken: string): Promise<boolean>;
15
+ listGames(query?: Record<string, any>): Promise<PagingResponse<any>>;
16
+ getGameDetail(gameId: string, bearerToken: string): Promise<any>;
17
+ listRecentPlayed(bearerToken: string, query?: Record<string, any>): Promise<PagingResponse<any>>;
18
+ trackPlay(bearerToken: string, gameId: string, playTimeSeconds?: number): Promise<boolean>;
19
+ trackMatchEnd(bearerToken: string, gameId: string, body: TrackMatchEndRequest): Promise<boolean>;
20
+ emitGameEvent(bearerToken: string, gameId: string, body: EmitGameEventRequest): Promise<EmitGameEventResponse>;
21
+ getBalances(bearerToken: string, query?: Record<string, any>): Promise<any>;
22
+ getBalanceHistory(bearerToken: string, query?: Record<string, any>): Promise<PagingResponse<any>>;
23
+ getMyProfile(bearerToken: string): Promise<any>;
24
+ getMyBalance(bearerToken: string): Promise<any>;
25
+ listReferrals(bearerToken: string, query?: Record<string, any>): Promise<PagingResponse<any>>;
26
+ setReferral(bearerToken: string, body: Record<string, any>): Promise<boolean>;
27
+ listTasks(bearerToken: string): Promise<any[]>;
28
+ listFinishedTasks(bearerToken: string): Promise<any[]>;
29
+ startTask(bearerToken: string, body: Record<string, any>): Promise<any>;
30
+ claimTask(bearerToken: string, body: Record<string, any>): Promise<any>;
31
+ getPlatformQuests(bearerToken: string, query?: Record<string, any>): Promise<any>;
32
+ getCampaignQuests(bearerToken: string, query?: Record<string, any>): Promise<any>;
33
+ claimQuest(bearerToken: string, questProgressId: string): Promise<any>;
34
+ claimMilestone(bearerToken: string, milestoneId: string, body: Record<string, any>): Promise<any>;
35
+ }
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './storage';
3
+ export * from './looplay-auth';
4
+ export * from './providers';
@@ -0,0 +1,19 @@
1
+ import { type AuthEventName, type AuthLoginParams, type LooplayAuthOptions, type LooplaySession } from './types';
2
+ type Listener = (session: LooplaySession | null) => void;
3
+ export declare class LooplayAuth {
4
+ private readonly provider;
5
+ private readonly storage;
6
+ private readonly key;
7
+ private session;
8
+ private readonly listeners;
9
+ constructor(options: LooplayAuthOptions);
10
+ init(): Promise<void>;
11
+ getSession(): LooplaySession | null;
12
+ login(params?: AuthLoginParams): Promise<LooplaySession>;
13
+ logout(): Promise<void>;
14
+ getAccessToken(): Promise<string | undefined>;
15
+ on(eventName: AuthEventName, listener: Listener): () => void;
16
+ private restoreFromStorage;
17
+ private setSession;
18
+ }
19
+ export {};
@@ -0,0 +1 @@
1
+ export * from './telegram-auth-provider';
@@ -0,0 +1,30 @@
1
+ import { type ServiceClientOptions } from '../../apps/service-client';
2
+ import type { AuthLoginParams, AuthLoginResult, AuthProvider, LooplaySession, LooplayUser } from '../types';
3
+ export interface TelegramAuthLoginParams extends AuthLoginParams {
4
+ telegramInitData?: string;
5
+ }
6
+ export interface TelegramAuthProviderOptions extends ServiceClientOptions {
7
+ /**
8
+ * Optional override for how to read Telegram init data.
9
+ * If omitted, provider will try `params.telegramInitData` then `globalThis.Telegram.WebApp.initData`.
10
+ */
11
+ getTelegramInitData?: () => string | undefined;
12
+ /**
13
+ * Optional mapper from backend user payload to LooplayUser.
14
+ * If omitted, provider will try common fields like id/_id/userId/telegramId.
15
+ */
16
+ mapUser?: (rawUser: Record<string, any>) => LooplayUser;
17
+ }
18
+ export declare class TelegramAuthProvider implements AuthProvider {
19
+ readonly id = "telegram";
20
+ private readonly client;
21
+ private readonly getTelegramInitData?;
22
+ private readonly mapUser?;
23
+ private session;
24
+ constructor(options: TelegramAuthProviderOptions);
25
+ onSessionChanged: (session: LooplaySession | null) => void;
26
+ login(params?: TelegramAuthLoginParams): Promise<AuthLoginResult>;
27
+ refresh(): Promise<Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>>;
28
+ logout(): Promise<void>;
29
+ private defaultMapUser;
30
+ }
@@ -0,0 +1,12 @@
1
+ import type { AuthStorage } from './types';
2
+ export declare class MemoryAuthStorage implements AuthStorage {
3
+ private readonly map;
4
+ getItem(key: string): Promise<string | null>;
5
+ setItem(key: string, value: string): Promise<void>;
6
+ removeItem(key: string): Promise<void>;
7
+ }
8
+ export declare class BrowserLocalStorageAuthStorage implements AuthStorage {
9
+ getItem(key: string): Promise<string | null>;
10
+ setItem(key: string, value: string): Promise<void>;
11
+ removeItem(key: string): Promise<void>;
12
+ }
@@ -0,0 +1,46 @@
1
+ export type AuthEventName = 'sessionChanged' | 'login' | 'logout';
2
+ export interface LooplayUser {
3
+ id: string;
4
+ displayName?: string;
5
+ avatarUrl?: string;
6
+ }
7
+ export interface LooplaySession {
8
+ user: LooplayUser;
9
+ accessToken?: string;
10
+ refreshToken?: string;
11
+ expiresAt?: number;
12
+ }
13
+ export interface AuthLoginParams {
14
+ /** Optional hint to identify the player in your own system */
15
+ playerId?: string;
16
+ }
17
+ export interface AuthLoginResult {
18
+ session: LooplaySession;
19
+ }
20
+ export interface AuthProvider {
21
+ /** A stable provider id, e.g. "telegram", "oauth", "custom" */
22
+ readonly id: string;
23
+ /** Called once during SDK init */
24
+ init?: () => Promise<void>;
25
+ /**
26
+ * Optional hook called whenever LooplayAuth updates the active session
27
+ * (including restoring from storage).
28
+ */
29
+ onSessionChanged?: (session: LooplaySession | null) => void | Promise<void>;
30
+ /** Start interactive login and return a session */
31
+ login: (params?: AuthLoginParams) => Promise<AuthLoginResult>;
32
+ /** Logout and clear remote/local state */
33
+ logout: () => Promise<void>;
34
+ /** Optional: refresh access token */
35
+ refresh?: () => Promise<Pick<LooplaySession, 'accessToken' | 'refreshToken' | 'expiresAt'>>;
36
+ }
37
+ export interface AuthStorage {
38
+ getItem(key: string): Promise<string | null>;
39
+ setItem(key: string, value: string): Promise<void>;
40
+ removeItem(key: string): Promise<void>;
41
+ }
42
+ export interface LooplayAuthOptions {
43
+ provider: AuthProvider;
44
+ storage?: AuthStorage;
45
+ storageKeyPrefix?: string;
46
+ }
@@ -0,0 +1,15 @@
1
+ export declare class LooplaySDKError extends Error {
2
+ constructor(message?: string);
3
+ }
4
+ export declare class NotInitializedError extends LooplaySDKError {
5
+ constructor();
6
+ }
7
+ export declare class MissingBaseUrlError extends LooplaySDKError {
8
+ constructor();
9
+ }
10
+ export declare class MissingAuthError extends LooplaySDKError {
11
+ constructor();
12
+ }
13
+ export declare class NotAuthenticatedError extends LooplaySDKError {
14
+ constructor();
15
+ }
@@ -0,0 +1,6 @@
1
+ export * from './looplay-sdk';
2
+ export * from './types';
3
+ export * from './errors';
4
+ export * from './auth';
5
+ export * from './apps';
6
+ export type { GameEventKey, TrackMatchEndRequest, EmitGameEventRequest, EmitGameEventResponse, } from '@looplay/types';
@@ -0,0 +1,38 @@
1
+ import type { LooplayInitParams, LooplaySDKCreateOptions } from './types';
2
+ import { LooplayAuth } from './auth/looplay-auth';
3
+ import { ApiClient } from './apps/api-client';
4
+ import type { EmitGameEventResponse, GameEventKey } from './apps/LooplaySDK.types';
5
+ export declare class LooplaySDK {
6
+ readonly auth?: LooplayAuth;
7
+ readonly api?: ApiClient;
8
+ private gameId?;
9
+ private initialized;
10
+ constructor(options?: LooplaySDKCreateOptions);
11
+ init(params: LooplayInitParams): Promise<void>;
12
+ getAccessToken(): Promise<string | undefined>;
13
+ getGameId(): string | undefined;
14
+ getMyProfile(): Promise<any>;
15
+ trackPlay(playTimeSeconds?: number): Promise<boolean>;
16
+ /**
17
+ * Report that a match/round ended.
18
+ * Maps to PLAY_MATCH (and WIN_MATCH when isWin=true).
19
+ * matchId is the idempotency anchor — safe to call twice with the same matchId.
20
+ */
21
+ trackMatch(matchId: string, opts: {
22
+ durationSeconds: number;
23
+ isCompleted?: boolean;
24
+ isWin?: boolean;
25
+ }): Promise<boolean>;
26
+ /**
27
+ * Emit a custom action event (CUSTOM_ACTION metric).
28
+ * Use GameEventKey for platform-defined codes; custom strings for game-specific quests.
29
+ * Pass refId to make the call idempotent — same refId = same event, dedup-safe.
30
+ */
31
+ emit(actionCode: GameEventKey | string, opts?: {
32
+ value?: number;
33
+ refId?: string;
34
+ payload?: Record<string, unknown>;
35
+ }): Promise<EmitGameEventResponse>;
36
+ private assertInitialized;
37
+ private verifyGameId;
38
+ }
@@ -0,0 +1,13 @@
1
+ import type { LooplayAuthOptions } from './auth/types';
2
+ import type { FetchLike } from './apps/http';
3
+ export interface LooplaySDKCreateOptions {
4
+ auth?: LooplayAuthOptions;
5
+ baseUrl?: string;
6
+ fetch?: FetchLike;
7
+ defaultHeaders?: Record<string, string>;
8
+ }
9
+ export interface LooplayInitParams {
10
+ gameId: string;
11
+ /** 'none': skip verification | 'strict': verify via /games/:id (requires auth) */
12
+ verifyMode?: 'none' | 'strict';
13
+ }