@pokertools/sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -400,6 +400,8 @@ var PokerSocket = class _PokerSocket {
400
400
  this.shouldReconnect = true;
401
401
  // Latest state cache for each table
402
402
  this.stateCache = /* @__PURE__ */ new Map();
403
+ // Version metadata per table (exposed safely via getTableVersion)
404
+ this.tableVersions = /* @__PURE__ */ new Map();
403
405
  const wsUrl = new URL(config.url);
404
406
  wsUrl.searchParams.set("token", config.token);
405
407
  this.url = wsUrl.toString();
@@ -553,6 +555,7 @@ var PokerSocket = class _PokerSocket {
553
555
  }
554
556
  this.joinedTables.delete(tableId);
555
557
  this.stateCache.delete(tableId);
558
+ this.tableVersions.delete(tableId);
556
559
  const message = {
557
560
  type: "LEAVE",
558
561
  tableId
@@ -571,6 +574,13 @@ var PokerSocket = class _PokerSocket {
571
574
  getCachedState(tableId) {
572
575
  return this.stateCache.get(tableId);
573
576
  }
577
+ /**
578
+ * Get latest known version for a table
579
+ * Returns undefined if no version has been received
580
+ */
581
+ getTableVersion(tableId) {
582
+ return this.tableVersions.get(tableId);
583
+ }
574
584
  // ============================================================================
575
585
  // Event Handling
576
586
  // ============================================================================
@@ -666,6 +676,7 @@ var PokerSocket = class _PokerSocket {
666
676
  switch (message.type) {
667
677
  case "SNAPSHOT": {
668
678
  this.stateCache.set(message.tableId, message.state);
679
+ this.tableVersions.set(message.tableId, message.version);
669
680
  const pending = this.pendingRequests.get(`snapshot:${message.tableId}`);
670
681
  if (pending) {
671
682
  this.pendingRequests.delete(`snapshot:${message.tableId}`);
@@ -675,15 +686,12 @@ var PokerSocket = class _PokerSocket {
675
686
  break;
676
687
  }
677
688
  case "STATE_UPDATE": {
689
+ this.tableVersions.set(message.tableId, message.version);
678
690
  const cachedState = this.stateCache.get(message.tableId);
679
691
  if (cachedState) {
680
692
  const updatedState = { ...cachedState, version: message.version };
681
693
  this.stateCache.set(message.tableId, updatedState);
682
694
  this.emit("stateUpdate", message.tableId, updatedState);
683
- } else {
684
- this.emit("stateUpdate", message.tableId, {
685
- version: message.version
686
- });
687
695
  }
688
696
  break;
689
697
  }
@@ -943,8 +951,12 @@ function isSiweExpired(message) {
943
951
  }
944
952
  return new Date(parsed.expirationTime) < /* @__PURE__ */ new Date();
945
953
  }
946
- function createWithdrawalMessage(amount, destinationAddress) {
947
- return `Withdraw ${amount} USD to ${destinationAddress}`;
954
+ function createWithdrawalMessage(amount, destinationAddress, nonce, timestamp) {
955
+ const ts = timestamp ?? Date.now();
956
+ const baseMsg = `Withdraw ${amount} USD to ${destinationAddress}`;
957
+ return `${baseMsg}
958
+ Nonce: ${nonce}
959
+ Timestamp: ${ts}`;
948
960
  }
949
961
  function generateIdempotencyKey() {
950
962
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/client.ts","../src/socket.ts","../src/auth.ts","../src/utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SDK-specific types and configuration\n */\n\n/**\n * SDK configuration options\n */\nexport interface PokerSDKConfig {\n /** Base URL of the PokerTools API (e.g., \"https://api.poker.example.com\") */\n baseUrl: string;\n\n /** WebSocket URL (defaults to baseUrl with ws:// protocol) */\n wsUrl?: string;\n\n /** JWT token for authentication */\n token?: string;\n\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n\n /** Retry configuration */\n retry?: {\n /** Number of retries for failed requests (default: 3) */\n count?: number;\n /** Delay between retries in ms (default: 1000) */\n delay?: number;\n /** Exponential backoff multiplier (default: 2) */\n backoff?: number;\n };\n\n /** Custom fetch implementation (for React Native or custom environments) */\n fetch?: typeof fetch;\n\n /** Custom WebSocket implementation (for React Native or Node.js) */\n WebSocket?: typeof WebSocket;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Authentication state\n */\nexport interface AuthState {\n token: string | null;\n user: {\n id: string;\n username: string;\n address: string;\n } | null;\n isAuthenticated: boolean;\n}\n\n/**\n * User balance information\n */\nexport interface UserBalances {\n main: number;\n inPlay: number;\n}\n\n/**\n * User profile with balances\n */\nexport interface UserProfile {\n id: string;\n username: string;\n address: string;\n role: \"PLAYER\" | \"ADMIN\" | \"BOT\";\n createdAt: string;\n balances: UserBalances;\n}\n\n/**\n * Blockchain configuration\n */\nexport interface BlockchainInfo {\n id: string;\n name: string;\n chainId: number;\n tokens: TokenInfo[];\n}\n\n/**\n * Token configuration\n */\nexport interface TokenInfo {\n id: string;\n symbol: string;\n name: string;\n decimals: number;\n minDeposit: string;\n}\n\n/**\n * Deposit session info\n */\nexport interface DepositSession {\n address: string;\n expiresAt: string;\n message: string;\n}\n\n/**\n * Deposit record\n */\nexport interface DepositRecord {\n id: string;\n txHash: string | null;\n chain: string;\n token: string;\n amountRaw: string;\n amountCredit: number;\n status: \"PENDING\" | \"PROCESSING\" | \"CONFIRMED\" | \"FAILED\";\n createdAt: string;\n confirmedAt: string | null;\n explorerUrl: string;\n}\n\n/**\n * Withdrawal request\n */\nexport interface WithdrawalRequest {\n amount: number;\n blockchainId: string;\n tokenId: string;\n address: string;\n message: string;\n signature: `0x${string}`;\n}\n\n/**\n * Withdrawal record\n */\nexport interface WithdrawalRecord {\n id: string;\n txHash: string | null;\n chain: string;\n token: string;\n address: string;\n amountRaw: string;\n amountUSD: number;\n status: \"PENDING\" | \"PROCESSING\" | \"CONFIRMED\" | \"FAILED\" | \"REJECTED\" | \"CANCELLED\";\n createdAt: string;\n confirmedAt: string | null;\n explorerUrl: string | null;\n}\n\n/**\n * Hand history entry (simplified)\n */\nexport interface HandHistoryEntry {\n id: string;\n amount: number;\n type: \"HAND_WIN\" | \"HAND_LOSS\";\n referenceId: string | null;\n createdAt: string;\n}\n\n/**\n * Player note\n */\nexport interface PlayerNote {\n id: string;\n targetId: string;\n content: string;\n label: string | null;\n createdAt: string;\n updatedAt: string;\n target?: {\n id: string;\n username: string;\n };\n}\n\n/**\n * SDK error class\n */\nexport class PokerSDKError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"PokerSDKError\";\n }\n}\n\n/**\n * WebSocket connection state\n */\nexport type ConnectionState = \"disconnected\" | \"connecting\" | \"connected\" | \"reconnecting\";\n\n/**\n * Event emitter types\n */\nexport interface PokerSocketEvents {\n connect: () => void;\n disconnect: (reason?: string) => void;\n reconnect: (attempt: number) => void;\n error: (error: Error) => void;\n stateUpdate: (tableId: string, state: import(\"@pokertools/types\").PublicState) => void;\n snapshot: (tableId: string, state: import(\"@pokertools/types\").PublicState) => void;\n action: (tableId: string, playerId: string, actionType: string, amount?: number) => void;\n}\n\n/**\n * Type-safe event listener\n */\nexport type EventListener<T extends keyof PokerSocketEvents> = PokerSocketEvents[T];\n","/**\n * PokerClient - HTTP client for PokerTools REST API\n *\n * Provides type-safe methods for all API endpoints with automatic\n * retry, authentication, and error handling.\n */\n\nimport type {\n PublicState,\n CreateTableRequest,\n BuyInRequest,\n AddChipsRequest,\n GameActionRequest,\n LoginRequest,\n LoginResponse,\n NonceResponse,\n TableListItem,\n} from \"@pokertools/types\";\n\nimport {\n PokerSDKConfig,\n PokerSDKError,\n UserProfile,\n BlockchainInfo,\n DepositSession,\n DepositRecord,\n WithdrawalRequest,\n WithdrawalRecord,\n HandHistoryEntry,\n PlayerNote,\n} from \"./types\";\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG = {\n timeout: 30000,\n retry: {\n count: 3,\n delay: 1000,\n backoff: 2,\n },\n};\n\n/**\n * PokerClient - Main HTTP client for PokerTools API\n *\n * @example\n * ```typescript\n * const client = new PokerClient({\n * baseUrl: \"https://api.poker.example.com\",\n * token: \"jwt-token\",\n * });\n *\n * // Get tables\n * const tables = await client.getTables();\n *\n * // Create a table\n * const tableId = await client.createTable({\n * name: \"My Table\",\n * mode: \"CASH\",\n * smallBlind: 5,\n * bigBlind: 10,\n * maxPlayers: 6,\n * });\n *\n * // Buy in\n * await client.buyIn(tableId, {\n * amount: 500,\n * seat: 3,\n * idempotencyKey: crypto.randomUUID(),\n * });\n * ```\n */\nexport class PokerClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly retry: Required<NonNullable<PokerSDKConfig[\"retry\"]>>;\n private readonly fetchFn: typeof fetch;\n private readonly debug: boolean;\n\n private token: string | null;\n\n constructor(config: PokerSDKConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.timeout = config.timeout ?? DEFAULT_CONFIG.timeout;\n this.retry = {\n count: config.retry?.count ?? DEFAULT_CONFIG.retry.count,\n delay: config.retry?.delay ?? DEFAULT_CONFIG.retry.delay,\n backoff: config.retry?.backoff ?? DEFAULT_CONFIG.retry.backoff,\n };\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.debug = config.debug ?? false;\n this.token = config.token ?? null;\n }\n\n // ============================================================================\n // Configuration\n // ============================================================================\n\n /**\n * Set the authentication token\n */\n setToken(token: string | null): void {\n this.token = token;\n }\n\n /**\n * Get current token\n */\n getToken(): string | null {\n return this.token;\n }\n\n /**\n * Check if client is authenticated\n */\n isAuthenticated(): boolean {\n return this.token !== null;\n }\n\n // ============================================================================\n // Authentication\n // ============================================================================\n\n /**\n * Get a nonce for SIWE authentication\n */\n async getNonce(): Promise<string> {\n const response = await this.request<NonceResponse>(\"POST\", \"/auth/nonce\");\n return response.nonce;\n }\n\n /**\n * Login with SIWE signature\n */\n async login(request: LoginRequest): Promise<LoginResponse> {\n const response = await this.request<LoginResponse>(\"POST\", \"/auth/login\", request);\n this.token = response.token;\n return response;\n }\n\n /**\n * Logout and revoke session\n */\n async logout(): Promise<void> {\n await this.request(\"POST\", \"/auth/logout\");\n this.token = null;\n }\n\n // ============================================================================\n // Tables\n // ============================================================================\n\n /**\n * Get list of active tables\n */\n async getTables(): Promise<TableListItem[]> {\n const response = await this.request<{ tables: TableListItem[] }>(\"GET\", \"/tables\");\n return response.tables;\n }\n\n /**\n * Create a new table\n */\n async createTable(config: CreateTableRequest): Promise<string> {\n const response = await this.request<{ tableId: string }>(\"POST\", \"/tables\", config);\n return response.tableId;\n }\n\n /**\n * Get table state\n * @param tableId - Table ID\n * @param since - Optional version for conditional fetch (returns null if unchanged)\n */\n async getTableState(tableId: string, since?: number): Promise<PublicState | null> {\n const query = since !== undefined ? `?since=${since}` : \"\";\n try {\n const response = await this.request<{ state: PublicState }>(\n \"GET\",\n `/tables/${tableId}${query}`\n );\n return response.state;\n } catch (error) {\n if (error instanceof PokerSDKError && error.statusCode === 304) {\n return null; // Not modified\n }\n throw error;\n }\n }\n\n /**\n * Buy in to a table\n */\n async buyIn(tableId: string, request: BuyInRequest): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/buy-in`, request);\n }\n\n /**\n * Execute a game action\n */\n async action(tableId: string, request: GameActionRequest): Promise<PublicState> {\n const response = await this.request<{ state: PublicState }>(\n \"POST\",\n `/tables/${tableId}/action`,\n request\n );\n return response.state;\n }\n\n /**\n * Add chips to stack (rebuy/top-up)\n */\n async addChips(tableId: string, request: AddChipsRequest): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/add-chips`, request);\n }\n\n /**\n * Stand from table (leave and cash out)\n */\n async stand(tableId: string): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/stand`);\n }\n\n // ============================================================================\n // Convenience Action Methods\n // ============================================================================\n\n /**\n * Fold hand\n */\n async fold(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"FOLD\" });\n }\n\n /**\n * Check (pass action)\n */\n async check(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"CHECK\" });\n }\n\n /**\n * Call current bet\n */\n async call(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"CALL\" });\n }\n\n /**\n * Place a bet\n */\n async bet(tableId: string, amount: number): Promise<PublicState> {\n return this.action(tableId, { type: \"BET\", amount });\n }\n\n /**\n * Raise the current bet\n */\n async raise(tableId: string, amount: number): Promise<PublicState> {\n return this.action(tableId, { type: \"RAISE\", amount });\n }\n\n /**\n * Deal new hand\n */\n async deal(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"DEAL\" });\n }\n\n /**\n * Show cards at showdown\n */\n async show(tableId: string, cardIndices?: number[]): Promise<PublicState> {\n return this.action(tableId, { type: \"SHOW\", cardIndices });\n }\n\n /**\n * Muck cards at showdown\n */\n async muck(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"MUCK\" });\n }\n\n /**\n * Use time bank\n */\n async timeBank(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"TIME_BANK\" });\n }\n\n // ============================================================================\n // User\n // ============================================================================\n\n /**\n * Get current user profile and balances\n */\n async getProfile(): Promise<UserProfile> {\n return this.request<UserProfile>(\"GET\", \"/user/me\");\n }\n\n /**\n * Get hand history\n */\n async getHandHistory(): Promise<HandHistoryEntry[]> {\n const response = await this.request<{ history: HandHistoryEntry[] }>(\"GET\", \"/user/history\");\n return response.history;\n }\n\n /**\n * Request a withdrawal\n */\n async withdraw(request: WithdrawalRequest): Promise<{\n id: string;\n status: string;\n amount: number;\n destination: string;\n blockchain: string;\n token: string;\n }> {\n return this.request(\"POST\", \"/user/withdraw\", request);\n }\n\n /**\n * Get withdrawal history\n */\n async getWithdrawals(): Promise<WithdrawalRecord[]> {\n const response = await this.request<{ withdrawals: WithdrawalRecord[] }>(\n \"GET\",\n \"/user/withdrawals\"\n );\n return response.withdrawals;\n }\n\n // ============================================================================\n // Finance\n // ============================================================================\n\n /**\n * Get supported blockchains and tokens\n */\n async getChains(): Promise<BlockchainInfo[]> {\n return this.request<BlockchainInfo[]>(\"GET\", \"/finance/chains\");\n }\n\n /**\n * Start deposit monitoring session\n */\n async startDeposit(): Promise<DepositSession> {\n return this.request<DepositSession>(\"POST\", \"/finance/deposit/start\");\n }\n\n /**\n * Get deposit address\n */\n async getDepositAddress(): Promise<string> {\n const response = await this.request<{ address: string }>(\"GET\", \"/finance/deposit/address\");\n return response.address;\n }\n\n /**\n * Get deposit history\n */\n async getDeposits(): Promise<DepositRecord[]> {\n const response = await this.request<{ deposits: DepositRecord[] }>(\"GET\", \"/finance/deposits\");\n return response.deposits;\n }\n\n // ============================================================================\n // Notes\n // ============================================================================\n\n /**\n * Get all notes by current user\n */\n async getNotes(): Promise<PlayerNote[]> {\n const response = await this.request<{ notes: PlayerNote[] }>(\"GET\", \"/notes\");\n return response.notes;\n }\n\n /**\n * Get note for specific player\n */\n async getNote(targetId: string): Promise<PlayerNote | null> {\n const response = await this.request<{ note: PlayerNote | null }>(\"GET\", `/notes/${targetId}`);\n return response.note;\n }\n\n /**\n * Save or update note\n */\n async saveNote(targetId: string, content: string, label?: string): Promise<PlayerNote> {\n const response = await this.request<{ note: PlayerNote }>(\"POST\", \"/notes\", {\n targetId,\n content,\n label,\n });\n return response.note;\n }\n\n /**\n * Delete note\n */\n async deleteNote(targetId: string): Promise<void> {\n await this.request(\"DELETE\", `/notes/${targetId}`);\n }\n\n // ============================================================================\n // Health\n // ============================================================================\n\n /**\n * Health check\n */\n async health(): Promise<{ status: string; timestamp: number }> {\n return this.request(\"GET\", \"/health\");\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Make HTTP request with retry logic\n */\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this.token) {\n headers.Authorization = `Bearer ${this.token}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.retry.count; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n if (this.debug) {\n console.log(`[PokerSDK] ${method} ${path}`, body);\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle 304 Not Modified\n if (response.status === 304) {\n throw new PokerSDKError(\"Not Modified\", \"NOT_MODIFIED\", 304);\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n message?: string;\n error?: string;\n code?: string;\n };\n\n throw new PokerSDKError(\n errorData.message ?? errorData.error ?? `HTTP ${response.status}`,\n errorData.code ?? errorData.error ?? \"HTTP_ERROR\",\n response.status,\n errorData\n );\n }\n\n const data = (await response.json()) as T;\n\n if (this.debug) {\n console.log(`[PokerSDK] Response:`, data);\n }\n\n return data;\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry client errors (4xx) except rate limiting\n if (error instanceof PokerSDKError) {\n if (\n error.statusCode &&\n error.statusCode >= 400 &&\n error.statusCode < 500 &&\n error.statusCode !== 429\n ) {\n throw error;\n }\n }\n\n // Don't retry on abort\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PokerSDKError(\"Request timeout\", \"TIMEOUT\", undefined, {\n timeout: this.timeout,\n });\n }\n\n // Retry with backoff\n if (attempt < this.retry.count) {\n const delay = this.retry.delay * Math.pow(this.retry.backoff, attempt);\n if (this.debug) {\n console.log(`[PokerSDK] Retry ${attempt + 1}/${this.retry.count} in ${delay}ms`);\n }\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError ?? new PokerSDKError(\"Request failed\", \"REQUEST_FAILED\");\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * PokerSocket - WebSocket client for real-time game updates\n *\n * Provides automatic reconnection, heartbeat, and typed event handling\n * for real-time poker game state synchronization.\n */\n\nimport type {\n PublicState,\n ClientMessage,\n JoinTableMessage,\n LeaveTableMessage,\n PingMessage,\n} from \"@pokertools/types\";\n\nimport { safeParseServerMessage } from \"@pokertools/types\";\n\nimport {\n PokerSDKConfig,\n PokerSDKError,\n ConnectionState,\n PokerSocketEvents,\n EventListener,\n} from \"./types\";\n\n/**\n * WebSocket configuration\n */\ninterface SocketConfig {\n /** WebSocket URL */\n url: string;\n /** JWT token for authentication */\n token: string;\n /** Heartbeat interval in ms (default: 25000) */\n heartbeatInterval?: number;\n /** Reconnection attempts (default: 10) */\n reconnectAttempts?: number;\n /** Base reconnection delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Max reconnection delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n /** Custom WebSocket implementation */\n WebSocket?: typeof WebSocket;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Default socket configuration\n */\nconst DEFAULT_SOCKET_CONFIG = {\n heartbeatInterval: 25000,\n reconnectAttempts: 10,\n reconnectDelay: 1000,\n maxReconnectDelay: 30000,\n};\n\n/**\n * PokerSocket - Real-time WebSocket client\n *\n * @example\n * ```typescript\n * const socket = new PokerSocket({\n * url: \"wss://api.poker.example.com/ws/play\",\n * token: \"jwt-token\",\n * });\n *\n * // Listen for events\n * socket.on(\"connect\", () => console.log(\"Connected!\"));\n * socket.on(\"stateUpdate\", (tableId, state) => {\n * console.log(\"State updated:\", state);\n * });\n *\n * // Connect\n * await socket.connect();\n *\n * // Join a table\n * await socket.join(\"table-123\");\n *\n * // Later: disconnect\n * socket.disconnect();\n * ```\n */\nexport class PokerSocket {\n private readonly url: string;\n private readonly token: string;\n private readonly heartbeatInterval: number;\n private readonly reconnectAttempts: number;\n private readonly reconnectDelay: number;\n private readonly maxReconnectDelay: number;\n private readonly WebSocketImpl: typeof WebSocket;\n private readonly debug: boolean;\n\n private ws: WebSocket | null = null;\n private connectionState: ConnectionState = \"disconnected\";\n private reconnectCount = 0;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private pendingRequests = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n }\n >();\n private joinedTables = new Set<string>();\n private listeners = new Map<\n keyof PokerSocketEvents,\n Set<EventListener<keyof PokerSocketEvents>>\n >();\n private shouldReconnect = true;\n\n // Latest state cache for each table\n private stateCache = new Map<string, PublicState>();\n\n constructor(config: SocketConfig) {\n // Construct WebSocket URL with token\n const wsUrl = new URL(config.url);\n wsUrl.searchParams.set(\"token\", config.token);\n this.url = wsUrl.toString();\n this.token = config.token;\n\n this.heartbeatInterval = config.heartbeatInterval ?? DEFAULT_SOCKET_CONFIG.heartbeatInterval;\n this.reconnectAttempts = config.reconnectAttempts ?? DEFAULT_SOCKET_CONFIG.reconnectAttempts;\n this.reconnectDelay = config.reconnectDelay ?? DEFAULT_SOCKET_CONFIG.reconnectDelay;\n this.maxReconnectDelay = config.maxReconnectDelay ?? DEFAULT_SOCKET_CONFIG.maxReconnectDelay;\n this.WebSocketImpl = config.WebSocket ?? globalThis.WebSocket;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Create a PokerSocket from SDK config\n */\n static fromConfig(config: PokerSDKConfig): PokerSocket {\n if (!config.token) {\n throw new PokerSDKError(\"Token is required for WebSocket connection\", \"AUTH_REQUIRED\");\n }\n\n const baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n const wsUrl = config.wsUrl ?? baseUrl.replace(/^http/, \"ws\") + \"/ws/play\";\n\n return new PokerSocket({\n url: wsUrl,\n token: config.token,\n WebSocket: config.WebSocket,\n debug: config.debug,\n });\n }\n\n // ============================================================================\n // Connection Management\n // ============================================================================\n\n /**\n * Connect to the WebSocket server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.connectionState === \"connected\") {\n resolve();\n return;\n }\n\n if (this.connectionState === \"connecting\") {\n // Wait for existing connection attempt\n const checkConnection = () => {\n if (this.connectionState === \"connected\") {\n resolve();\n } else if (this.connectionState === \"disconnected\") {\n reject(new PokerSDKError(\"Connection failed\", \"CONNECTION_FAILED\"));\n } else {\n setTimeout(checkConnection, 100);\n }\n };\n checkConnection();\n return;\n }\n\n this.shouldReconnect = true;\n this.connectionState = \"connecting\";\n this.log(\"Connecting to\", this.url);\n\n try {\n this.ws = new this.WebSocketImpl(this.url);\n\n this.ws.onopen = () => {\n this.connectionState = \"connected\";\n this.reconnectCount = 0;\n this.startHeartbeat();\n this.emit(\"connect\");\n this.log(\"Connected\");\n\n // Rejoin previously joined tables\n void this.rejoinTables();\n\n resolve();\n };\n\n this.ws.onclose = (event) => {\n this.handleDisconnect(event.reason || \"Connection closed\");\n };\n\n this.ws.onerror = (event) => {\n this.log(\"WebSocket error:\", event);\n if (this.connectionState === \"connecting\") {\n reject(new PokerSDKError(\"Connection failed\", \"CONNECTION_FAILED\"));\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data as string);\n };\n } catch (error) {\n this.connectionState = \"disconnected\";\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n this.shouldReconnect = false;\n this.stopHeartbeat();\n this.clearPendingRequests(\"Connection closed\");\n\n if (this.ws) {\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.connectionState = \"disconnected\";\n this.emit(\"disconnect\", \"Client disconnect\");\n this.log(\"Disconnected\");\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.connectionState;\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connectionState === \"connected\";\n }\n\n // ============================================================================\n // Table Subscription\n // ============================================================================\n\n /**\n * Join a table to receive real-time updates\n */\n async join(tableId: string): Promise<PublicState> {\n if (this.connectionState !== \"connected\") {\n throw new PokerSDKError(\"Not connected\", \"NOT_CONNECTED\");\n }\n\n const requestId = this.generateRequestId();\n const message: JoinTableMessage = {\n type: \"JOIN\",\n tableId,\n requestId,\n };\n\n this.joinedTables.add(tableId);\n this.send(message);\n\n // Wait for snapshot response\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new PokerSDKError(\"Join timeout\", \"TIMEOUT\"));\n }, 10000);\n\n // Store resolver for snapshot message\n this.pendingRequests.set(`snapshot:${tableId}`, {\n resolve: (state) => {\n clearTimeout(timeout);\n resolve(state as PublicState);\n },\n reject,\n timeout,\n });\n });\n }\n\n /**\n * Leave a table\n */\n leave(tableId: string): void {\n if (this.connectionState !== \"connected\") {\n return;\n }\n\n this.joinedTables.delete(tableId);\n this.stateCache.delete(tableId);\n\n const message: LeaveTableMessage = {\n type: \"LEAVE\",\n tableId,\n };\n\n this.send(message);\n }\n\n /**\n * Get currently joined tables\n */\n getJoinedTables(): string[] {\n return Array.from(this.joinedTables);\n }\n\n /**\n * Get cached state for a table\n */\n getCachedState(tableId: string): PublicState | undefined {\n return this.stateCache.get(tableId);\n }\n\n // ============================================================================\n // Event Handling\n // ============================================================================\n\n /**\n * Subscribe to an event\n */\n on<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n off<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener);\n }\n }\n\n /**\n * Subscribe to an event (once)\n */\n once<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): () => void {\n const onceWrapper = ((...args: Parameters<PokerSocketEvents[E]>) => {\n this.off(event, onceWrapper);\n (listener as (...args: unknown[]) => void)(...args);\n }) as PokerSocketEvents[E];\n\n return this.on(event, onceWrapper);\n }\n\n // ============================================================================\n // Ping\n // ============================================================================\n\n /**\n * Send application-level ping (not WebSocket ping)\n */\n async ping(): Promise<number> {\n if (this.connectionState !== \"connected\") {\n throw new PokerSDKError(\"Not connected\", \"NOT_CONNECTED\");\n }\n\n const requestId = this.generateRequestId();\n const startTime = Date.now();\n\n const message: PingMessage = {\n type: \"PING\",\n requestId,\n timestamp: startTime,\n };\n\n this.send(message);\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new PokerSDKError(\"Ping timeout\", \"TIMEOUT\"));\n }, 5000);\n\n this.pendingRequests.set(requestId, {\n resolve: () => {\n resolve(Date.now() - startTime);\n },\n reject,\n timeout,\n });\n });\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Send a message to the server\n */\n private send(message: ClientMessage): void {\n if (this.ws?.readyState !== this.WebSocketImpl.OPEN) {\n throw new PokerSDKError(\"WebSocket not open\", \"NOT_CONNECTED\");\n }\n\n this.log(\"Sending:\", message);\n this.ws.send(JSON.stringify(message));\n }\n\n /**\n * Handle incoming message\n */\n private handleMessage(data: string): void {\n try {\n const parsed: unknown = JSON.parse(data);\n const result = safeParseServerMessage(parsed);\n if (!result.success) {\n this.log(\"Invalid server message:\", result.error);\n return;\n }\n const message = result.data;\n this.log(\"Received:\", message);\n\n switch (message.type) {\n case \"SNAPSHOT\": {\n // Cache state\n this.stateCache.set(message.tableId, message.state);\n\n // Resolve pending join request\n const pending = this.pendingRequests.get(`snapshot:${message.tableId}`);\n if (pending) {\n this.pendingRequests.delete(`snapshot:${message.tableId}`);\n pending.resolve(message.state);\n }\n\n this.emit(\"snapshot\", message.tableId, message.state);\n break;\n }\n\n case \"STATE_UPDATE\": {\n // For lightweight updates, we need to fetch full state\n // The message only contains version info\n // Emit event so UI can decide to fetch or use existing data\n const cachedState = this.stateCache.get(message.tableId);\n if (cachedState) {\n // Update version in cache\n const updatedState = { ...cachedState, version: message.version };\n this.stateCache.set(message.tableId, updatedState);\n this.emit(\"stateUpdate\", message.tableId, updatedState);\n } else {\n // No cached state, emit with minimal info\n this.emit(\"stateUpdate\", message.tableId, {\n version: message.version,\n } as PublicState);\n }\n break;\n }\n\n case \"ACTION\": {\n this.emit(\n \"action\",\n message.tableId,\n message.playerId,\n message.actionType,\n message.amount\n );\n break;\n }\n\n case \"ACK\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.resolve(undefined);\n }\n break;\n }\n\n case \"PONG\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.resolve(message.timestamp);\n }\n break;\n }\n\n case \"ERROR\": {\n this.log(\"Server error:\", message);\n if (message.requestId) {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.reject(new PokerSDKError(message.message, message.code));\n }\n }\n this.emit(\"error\", new PokerSDKError(message.message, message.code));\n break;\n }\n }\n } catch (error) {\n this.log(\"Failed to parse message:\", error);\n }\n }\n\n /**\n * Handle disconnect\n */\n private handleDisconnect(reason: string): void {\n this.stopHeartbeat();\n this.ws = null;\n\n const wasConnected = this.connectionState === \"connected\";\n this.connectionState = \"disconnected\";\n\n if (wasConnected) {\n this.emit(\"disconnect\", reason);\n }\n\n // Attempt reconnection if enabled\n if (this.shouldReconnect && this.reconnectCount < this.reconnectAttempts) {\n void this.reconnect();\n }\n }\n\n /**\n * Attempt to reconnect\n */\n private async reconnect(): Promise<void> {\n this.reconnectCount++;\n this.connectionState = \"reconnecting\";\n\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectCount - 1),\n this.maxReconnectDelay\n );\n\n this.log(\n `Reconnecting in ${delay}ms (attempt ${this.reconnectCount}/${this.reconnectAttempts})`\n );\n this.emit(\"reconnect\", this.reconnectCount);\n\n await this.sleep(delay);\n\n if (!this.shouldReconnect) {\n return;\n }\n\n try {\n await this.connect();\n } catch {\n // connect() handles its own errors\n }\n }\n\n /**\n * Rejoin previously joined tables\n */\n private async rejoinTables(): Promise<void> {\n for (const tableId of this.joinedTables) {\n try {\n await this.join(tableId);\n } catch (error) {\n this.log(\"Failed to rejoin table:\", tableId, error);\n }\n }\n }\n\n /**\n * Start heartbeat timer\n */\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n if (this.connectionState === \"connected\") {\n void this.ping().catch(() => {\n // Ping failed, connection might be dead\n this.log(\"Heartbeat failed\");\n });\n }\n }, this.heartbeatInterval);\n }\n\n /**\n * Stop heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n /**\n * Clear all pending requests\n */\n private clearPendingRequests(reason: string): void {\n for (const pending of this.pendingRequests.values()) {\n clearTimeout(pending.timeout);\n\n pending.reject(new PokerSDKError(reason, \"CONNECTION_CLOSED\"));\n }\n this.pendingRequests.clear();\n }\n\n /**\n * Emit event to listeners\n */\n private emit<E extends keyof PokerSocketEvents>(\n event: E,\n ...args: Parameters<PokerSocketEvents[E]>\n ): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n for (const listener of listeners) {\n try {\n (listener as (...args: unknown[]) => void)(...args);\n } catch (error) {\n this.log(\"Listener error:\", error);\n }\n }\n }\n }\n\n /**\n * Generate unique request ID\n */\n private generateRequestId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Debug logger\n */\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PokerSocket]\", ...args);\n }\n }\n}\n","/**\n * Authentication helpers for SIWE (Sign-In with Ethereum)\n *\n * These utilities help construct SIWE messages for wallet signing.\n */\n\n/**\n * SIWE message parameters\n */\nexport interface SiweMessageParams {\n /** Domain making the request (e.g., \"poker.example.com\") */\n domain: string;\n /** Ethereum address (checksummed) */\n address: string;\n /** Human-readable statement (optional) */\n statement?: string;\n /** URI of the signing resource */\n uri: string;\n /** Current version of the message (always \"1\") */\n version?: \"1\";\n /** Chain ID */\n chainId?: number;\n /** Nonce from server */\n nonce: string;\n /** Issued at timestamp (ISO 8601) */\n issuedAt?: string;\n /** Expiration time (ISO 8601) */\n expirationTime?: string;\n /** Not before time (ISO 8601) */\n notBefore?: string;\n /** Request ID */\n requestId?: string;\n /** Resources (URIs) */\n resources?: string[];\n}\n\n/**\n * Create a SIWE message string for signing\n *\n * @example\n * ```typescript\n * import { createSiweMessage } from \"@pokertools/sdk\";\n *\n * // Get nonce from server\n * const nonce = await client.getNonce();\n *\n * // Create message\n * const message = createSiweMessage({\n * domain: \"poker.example.com\",\n * address: \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n * uri: \"https://poker.example.com\",\n * nonce,\n * statement: \"Sign in to PokerTools\",\n * });\n *\n * // Sign with wallet (e.g., wagmi, ethers, viem)\n * const signature = await signMessage({ message });\n *\n * // Login\n * const { token, user } = await client.login({ message, signature });\n * ```\n */\nexport function createSiweMessage(params: SiweMessageParams): string {\n const {\n domain,\n address,\n statement,\n uri,\n version = \"1\",\n chainId = 1,\n nonce,\n issuedAt = new Date().toISOString(),\n expirationTime,\n notBefore,\n requestId,\n resources,\n } = params;\n\n // Build message following EIP-4361 spec\n const lines: string[] = [];\n\n // Header\n lines.push(`${domain} wants you to sign in with your Ethereum account:`);\n lines.push(address);\n\n // Statement (optional)\n if (statement) {\n lines.push(\"\");\n lines.push(statement);\n }\n\n // Required fields\n lines.push(\"\");\n lines.push(`URI: ${uri}`);\n lines.push(`Version: ${version}`);\n lines.push(`Chain ID: ${chainId}`);\n lines.push(`Nonce: ${nonce}`);\n lines.push(`Issued At: ${issuedAt}`);\n\n // Optional fields\n if (expirationTime) {\n lines.push(`Expiration Time: ${expirationTime}`);\n }\n if (notBefore) {\n lines.push(`Not Before: ${notBefore}`);\n }\n if (requestId) {\n lines.push(`Request ID: ${requestId}`);\n }\n if (resources && resources.length > 0) {\n lines.push(`Resources:`);\n for (const resource of resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Parse a SIWE message string back into params\n */\nexport function parseSiweMessage(message: string): Partial<SiweMessageParams> {\n const lines = message.split(\"\\n\");\n const result: Partial<SiweMessageParams> = {};\n\n // First line: domain\n const domainMatch = /^(.+) wants you to sign in with your Ethereum account:$/.exec(lines[0]);\n if (domainMatch) {\n result.domain = domainMatch[1];\n }\n\n // Second line: address\n if (lines[1]) {\n result.address = lines[1];\n }\n\n // Parse key-value pairs\n for (const line of lines) {\n if (line.startsWith(\"URI: \")) {\n result.uri = line.slice(5);\n } else if (line.startsWith(\"Version: \")) {\n result.version = line.slice(9) as \"1\";\n } else if (line.startsWith(\"Chain ID: \")) {\n result.chainId = parseInt(line.slice(10), 10);\n } else if (line.startsWith(\"Nonce: \")) {\n result.nonce = line.slice(7);\n } else if (line.startsWith(\"Issued At: \")) {\n result.issuedAt = line.slice(11);\n } else if (line.startsWith(\"Expiration Time: \")) {\n result.expirationTime = line.slice(17);\n } else if (line.startsWith(\"Not Before: \")) {\n result.notBefore = line.slice(12);\n } else if (line.startsWith(\"Request ID: \")) {\n result.requestId = line.slice(12);\n }\n }\n\n // Parse statement (lines between address and URI)\n const uriIndex = lines.findIndex((l) => l.startsWith(\"URI: \"));\n if (uriIndex > 3) {\n const statementLines = lines.slice(3, uriIndex - 1).filter((l) => l.trim());\n if (statementLines.length > 0) {\n result.statement = statementLines.join(\"\\n\");\n }\n }\n\n return result;\n}\n\n/**\n * Check if a SIWE message is expired\n */\nexport function isSiweExpired(message: string): boolean {\n const parsed = parseSiweMessage(message);\n if (!parsed.expirationTime) {\n return false;\n }\n return new Date(parsed.expirationTime) < new Date();\n}\n\n/**\n * Create a withdrawal message for signing\n *\n * @example\n * ```typescript\n * const message = createWithdrawalMessage(100, \"0x...\");\n * const signature = await signMessage({ message });\n * await client.withdraw({ amount: 100, address: \"0x...\", message, signature, ... });\n * ```\n */\nexport function createWithdrawalMessage(amount: number, destinationAddress: string): string {\n return `Withdraw ${amount} USD to ${destinationAddress}`;\n}\n\n/**\n * Generate a random idempotency key\n * Uses crypto.randomUUID if available, otherwise falls back to timestamp + random\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}-${Math.random().toString(36).substr(2, 9)}`;\n}\n","/**\n * Utility functions for the PokerTools SDK\n */\n\nimport type { PublicState, PublicPlayer } from \"@pokertools/types\";\n\n/**\n * Format chip amount to display string\n * @param chips - Amount in cents (1 chip = 1 cent)\n * @param currency - Currency symbol (default: \"$\")\n */\nexport function formatChips(chips: number, currency = \"$\"): string {\n const dollars = chips / 100;\n return `${currency}${dollars.toFixed(2)}`;\n}\n\n/**\n * Parse display amount to chips (cents)\n * @param amount - Display amount string (e.g., \"$10.50\", \"10.50\", \"1050\")\n */\nexport function parseChips(amount: string): number {\n // Remove currency symbols and whitespace\n const cleaned = amount.replace(/[$€£¥,\\s]/g, \"\");\n const value = parseFloat(cleaned);\n\n if (isNaN(value)) {\n throw new Error(`Invalid amount: ${amount}`);\n }\n\n // If it looks like it's already in cents (integer), return as-is\n if (Number.isInteger(value) && value >= 100) {\n return value;\n }\n\n // Otherwise, convert from dollars to cents\n return Math.round(value * 100);\n}\n\n/**\n * Get the player whose turn it is\n */\nexport function getActivePlayer(state: PublicState): PublicPlayer | null {\n if (state.actionTo === null) {\n return null;\n }\n return state.players[state.actionTo] ?? null;\n}\n\n/**\n * Get player by ID\n */\nexport function getPlayerById(state: PublicState, playerId: string): PublicPlayer | null {\n return state.players.find((p) => p?.id === playerId) ?? null;\n}\n\n/**\n * Get player seat index by ID\n */\nexport function getPlayerSeat(state: PublicState, playerId: string): number | null {\n const index = state.players.findIndex((p) => p?.id === playerId);\n return index === -1 ? null : index;\n}\n\n/**\n * Check if it's a specific player's turn\n */\nexport function isPlayerTurn(state: PublicState, playerId: string): boolean {\n if (state.actionTo === null) {\n return false;\n }\n const player = state.players[state.actionTo];\n return player?.id === playerId;\n}\n\n/**\n * Get the amount needed to call\n */\nexport function getCallAmount(state: PublicState, playerId: string): number {\n const player = getPlayerById(state, playerId);\n if (!player) {\n return 0;\n }\n\n const currentBet = player.betThisStreet;\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return Math.min(highestBet - currentBet, player.stack);\n}\n\n/**\n * Get minimum raise amount\n */\nexport function getMinRaise(state: PublicState): number {\n return state.minRaise ?? state.config.bigBlind;\n}\n\n/**\n * Check if player can check\n */\nexport function canCheck(state: PublicState, playerId: string): boolean {\n const player = getPlayerById(state, playerId);\n if (!player || !isPlayerTurn(state, playerId)) {\n return false;\n }\n\n const currentBet = player.betThisStreet;\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return currentBet >= highestBet;\n}\n\n/**\n * Check if player can bet (no prior bets this round)\n */\nexport function canBet(state: PublicState, playerId: string): boolean {\n const player = getPlayerById(state, playerId);\n if (!player || !isPlayerTurn(state, playerId)) {\n return false;\n }\n\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return highestBet === 0 && player.stack > 0;\n}\n\n/**\n * Get total pot size (main pot + side pots)\n */\nexport function getTotalPot(state: PublicState): number {\n return state.pots.reduce((sum, pot) => sum + pot.amount, 0);\n}\n\n/**\n * Get number of active players (not folded, has chips)\n */\nexport function getActivePlayers(state: PublicState): PublicPlayer[] {\n return state.players.filter(\n (p): p is PublicPlayer => p !== null && p.status !== \"FOLDED\" && p.stack > 0\n );\n}\n\n/**\n * Get number of players in hand (not folded)\n */\nexport function getPlayersInHand(state: PublicState): PublicPlayer[] {\n return state.players.filter((p): p is PublicPlayer => p !== null && p.status !== \"FOLDED\");\n}\n\n/**\n * Card suit to emoji\n */\nexport function suitToEmoji(suit: string): string {\n const suits: Record<string, string> = {\n s: \"♠\",\n h: \"♥\",\n d: \"♦\",\n c: \"♣\",\n };\n return suits[suit.toLowerCase()] ?? suit;\n}\n\n/**\n * Format card for display (e.g., \"As\" -> \"A♠\")\n */\nexport function formatCard(card: string): string {\n if (card.length !== 2) {\n return card;\n }\n const rank = card[0].toUpperCase();\n const suit = suitToEmoji(card[1]);\n return `${rank}${suit}`;\n}\n\n/**\n * Format card array for display\n */\nexport function formatCards(cards: Array<string | null> | null): string {\n if (!cards) {\n return \"🂠🂠\";\n }\n return cards.map((c) => (c ? formatCard(c) : \"🂠\")).join(\" \");\n}\n\n/**\n * Get street display name\n */\nexport function getStreetName(street: string): string {\n const names: Record<string, string> = {\n PREFLOP: \"Pre-Flop\",\n FLOP: \"Flop\",\n TURN: \"Turn\",\n RIVER: \"River\",\n SHOWDOWN: \"Showdown\",\n };\n return names[street] ?? street;\n}\n\n/**\n * Check if game is in showdown phase\n */\nexport function isShowdown(state: PublicState): boolean {\n return state.street === \"SHOWDOWN\";\n}\n\n/**\n * Check if hand is complete (has winners)\n */\nexport function isHandComplete(state: PublicState): boolean {\n return state.winners !== undefined && state.winners !== null;\n}\n\n/**\n * Calculate pot odds as a ratio\n */\nexport function getPotOdds(state: PublicState, playerId: string): number {\n const callAmount = getCallAmount(state, playerId);\n if (callAmount === 0) {\n return Infinity;\n }\n return getTotalPot(state) / callAmount;\n}\n\n/**\n * Abbreviate large numbers (e.g., 1000 -> \"1K\")\n */\nexport function abbreviateNumber(num: number): string {\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1)}M`;\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1)}K`;\n }\n return num.toString();\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/client.ts","../src/socket.ts","../src/auth.ts","../src/utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SDK-specific types and configuration\n */\n\n/**\n * SDK configuration options\n */\nexport interface PokerSDKConfig {\n /** Base URL of the PokerTools API (e.g., \"https://api.poker.example.com\") */\n baseUrl: string;\n\n /** WebSocket URL (defaults to baseUrl with ws:// protocol) */\n wsUrl?: string;\n\n /** JWT token for authentication */\n token?: string;\n\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n\n /** Retry configuration */\n retry?: {\n /** Number of retries for failed requests (default: 3) */\n count?: number;\n /** Delay between retries in ms (default: 1000) */\n delay?: number;\n /** Exponential backoff multiplier (default: 2) */\n backoff?: number;\n };\n\n /** Custom fetch implementation (for React Native or custom environments) */\n fetch?: typeof fetch;\n\n /** Custom WebSocket implementation (for React Native or Node.js) */\n WebSocket?: typeof WebSocket;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Authentication state\n */\nexport interface AuthState {\n token: string | null;\n user: {\n id: string;\n username: string;\n address: string;\n } | null;\n isAuthenticated: boolean;\n}\n\n/**\n * User balance information\n */\nexport interface UserBalances {\n main: number;\n inPlay: number;\n}\n\n/**\n * User profile with balances\n */\nexport interface UserProfile {\n id: string;\n username: string;\n address: string;\n role: \"PLAYER\" | \"ADMIN\" | \"BOT\";\n createdAt: string;\n balances: UserBalances;\n}\n\n/**\n * Blockchain configuration\n */\nexport interface BlockchainInfo {\n id: string;\n name: string;\n chainId: number;\n tokens: TokenInfo[];\n}\n\n/**\n * Token configuration\n */\nexport interface TokenInfo {\n id: string;\n symbol: string;\n name: string;\n decimals: number;\n minDeposit: string;\n}\n\n/**\n * Deposit session info\n */\nexport interface DepositSession {\n address: string;\n expiresAt: string;\n message: string;\n}\n\n/**\n * Deposit record\n */\nexport interface DepositRecord {\n id: string;\n txHash: string | null;\n chain: string;\n token: string;\n amountRaw: string;\n amountCredit: number;\n status: \"PENDING\" | \"PROCESSING\" | \"CONFIRMED\" | \"FAILED\";\n createdAt: string;\n confirmedAt: string | null;\n explorerUrl: string;\n}\n\n/**\n * Withdrawal request\n */\nexport interface WithdrawalRequest {\n amount: number;\n blockchainId: string;\n tokenId: string;\n address: string;\n message: string;\n signature: `0x${string}`;\n}\n\n/**\n * Withdrawal record\n */\nexport interface WithdrawalRecord {\n id: string;\n txHash: string | null;\n chain: string;\n token: string;\n address: string;\n amountRaw: string;\n amountUSD: number;\n status: \"PENDING\" | \"PROCESSING\" | \"CONFIRMED\" | \"FAILED\" | \"REJECTED\" | \"CANCELLED\";\n createdAt: string;\n confirmedAt: string | null;\n explorerUrl: string | null;\n}\n\n/**\n * Hand history entry (simplified)\n */\nexport interface HandHistoryEntry {\n id: string;\n amount: number;\n type: \"HAND_WIN\" | \"HAND_LOSS\";\n referenceId: string | null;\n createdAt: string;\n}\n\n/**\n * Player note\n */\nexport interface PlayerNote {\n id: string;\n targetId: string;\n content: string;\n label: string | null;\n createdAt: string;\n updatedAt: string;\n target?: {\n id: string;\n username: string;\n };\n}\n\n/**\n * SDK error class\n */\nexport class PokerSDKError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode?: number,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"PokerSDKError\";\n }\n}\n\n/**\n * WebSocket connection state\n */\nexport type ConnectionState = \"disconnected\" | \"connecting\" | \"connected\" | \"reconnecting\";\n\n/**\n * Event emitter types\n */\nexport interface PokerSocketEvents {\n connect: () => void;\n disconnect: (reason?: string) => void;\n reconnect: (attempt: number) => void;\n error: (error: Error) => void;\n stateUpdate: (tableId: string, state: import(\"@pokertools/types\").PublicState) => void;\n snapshot: (tableId: string, state: import(\"@pokertools/types\").PublicState) => void;\n action: (tableId: string, playerId: string, actionType: string, amount?: number) => void;\n}\n\n/**\n * Type-safe event listener\n */\nexport type EventListener<T extends keyof PokerSocketEvents> = PokerSocketEvents[T];\n","/**\n * PokerClient - HTTP client for PokerTools REST API\n *\n * Provides type-safe methods for all API endpoints with automatic\n * retry, authentication, and error handling.\n */\n\nimport type {\n PublicState,\n CreateTableRequest,\n BuyInRequest,\n AddChipsRequest,\n GameActionRequest,\n LoginRequest,\n LoginResponse,\n NonceResponse,\n TableListItem,\n} from \"@pokertools/types\";\n\nimport {\n PokerSDKConfig,\n PokerSDKError,\n UserProfile,\n BlockchainInfo,\n DepositSession,\n DepositRecord,\n WithdrawalRequest,\n WithdrawalRecord,\n HandHistoryEntry,\n PlayerNote,\n} from \"./types\";\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG = {\n timeout: 30000,\n retry: {\n count: 3,\n delay: 1000,\n backoff: 2,\n },\n};\n\n/**\n * PokerClient - Main HTTP client for PokerTools API\n *\n * @example\n * ```typescript\n * const client = new PokerClient({\n * baseUrl: \"https://api.poker.example.com\",\n * token: \"jwt-token\",\n * });\n *\n * // Get tables\n * const tables = await client.getTables();\n *\n * // Create a table\n * const tableId = await client.createTable({\n * name: \"My Table\",\n * mode: \"CASH\",\n * smallBlind: 5,\n * bigBlind: 10,\n * maxPlayers: 6,\n * });\n *\n * // Buy in\n * await client.buyIn(tableId, {\n * amount: 500,\n * seat: 3,\n * idempotencyKey: crypto.randomUUID(),\n * });\n * ```\n */\nexport class PokerClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly retry: Required<NonNullable<PokerSDKConfig[\"retry\"]>>;\n private readonly fetchFn: typeof fetch;\n private readonly debug: boolean;\n\n private token: string | null;\n\n constructor(config: PokerSDKConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.timeout = config.timeout ?? DEFAULT_CONFIG.timeout;\n this.retry = {\n count: config.retry?.count ?? DEFAULT_CONFIG.retry.count,\n delay: config.retry?.delay ?? DEFAULT_CONFIG.retry.delay,\n backoff: config.retry?.backoff ?? DEFAULT_CONFIG.retry.backoff,\n };\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n this.debug = config.debug ?? false;\n this.token = config.token ?? null;\n }\n\n // ============================================================================\n // Configuration\n // ============================================================================\n\n /**\n * Set the authentication token\n */\n setToken(token: string | null): void {\n this.token = token;\n }\n\n /**\n * Get current token\n */\n getToken(): string | null {\n return this.token;\n }\n\n /**\n * Check if client is authenticated\n */\n isAuthenticated(): boolean {\n return this.token !== null;\n }\n\n // ============================================================================\n // Authentication\n // ============================================================================\n\n /**\n * Get a nonce for SIWE authentication\n */\n async getNonce(): Promise<string> {\n const response = await this.request<NonceResponse>(\"POST\", \"/auth/nonce\");\n return response.nonce;\n }\n\n /**\n * Login with SIWE signature\n */\n async login(request: LoginRequest): Promise<LoginResponse> {\n const response = await this.request<LoginResponse>(\"POST\", \"/auth/login\", request);\n this.token = response.token;\n return response;\n }\n\n /**\n * Logout and revoke session\n */\n async logout(): Promise<void> {\n await this.request(\"POST\", \"/auth/logout\");\n this.token = null;\n }\n\n // ============================================================================\n // Tables\n // ============================================================================\n\n /**\n * Get list of active tables\n */\n async getTables(): Promise<TableListItem[]> {\n const response = await this.request<{ tables: TableListItem[] }>(\"GET\", \"/tables\");\n return response.tables;\n }\n\n /**\n * Create a new table\n */\n async createTable(config: CreateTableRequest): Promise<string> {\n const response = await this.request<{ tableId: string }>(\"POST\", \"/tables\", config);\n return response.tableId;\n }\n\n /**\n * Get table state\n * @param tableId - Table ID\n * @param since - Optional version for conditional fetch (returns null if unchanged)\n */\n async getTableState(tableId: string, since?: number): Promise<PublicState | null> {\n const query = since !== undefined ? `?since=${since}` : \"\";\n try {\n const response = await this.request<{ state: PublicState }>(\n \"GET\",\n `/tables/${tableId}${query}`\n );\n return response.state;\n } catch (error) {\n if (error instanceof PokerSDKError && error.statusCode === 304) {\n return null; // Not modified\n }\n throw error;\n }\n }\n\n /**\n * Buy in to a table\n */\n async buyIn(tableId: string, request: BuyInRequest): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/buy-in`, request);\n }\n\n /**\n * Execute a game action\n */\n async action(tableId: string, request: GameActionRequest): Promise<PublicState> {\n const response = await this.request<{ state: PublicState }>(\n \"POST\",\n `/tables/${tableId}/action`,\n request\n );\n return response.state;\n }\n\n /**\n * Add chips to stack (rebuy/top-up)\n */\n async addChips(tableId: string, request: AddChipsRequest): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/add-chips`, request);\n }\n\n /**\n * Stand from table (leave and cash out)\n */\n async stand(tableId: string): Promise<void> {\n await this.request(\"POST\", `/tables/${tableId}/stand`);\n }\n\n // ============================================================================\n // Convenience Action Methods\n // ============================================================================\n\n /**\n * Fold hand\n */\n async fold(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"FOLD\" });\n }\n\n /**\n * Check (pass action)\n */\n async check(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"CHECK\" });\n }\n\n /**\n * Call current bet\n */\n async call(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"CALL\" });\n }\n\n /**\n * Place a bet\n */\n async bet(tableId: string, amount: number): Promise<PublicState> {\n return this.action(tableId, { type: \"BET\", amount });\n }\n\n /**\n * Raise the current bet\n */\n async raise(tableId: string, amount: number): Promise<PublicState> {\n return this.action(tableId, { type: \"RAISE\", amount });\n }\n\n /**\n * Deal new hand\n */\n async deal(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"DEAL\" });\n }\n\n /**\n * Show cards at showdown\n */\n async show(tableId: string, cardIndices?: number[]): Promise<PublicState> {\n return this.action(tableId, { type: \"SHOW\", cardIndices });\n }\n\n /**\n * Muck cards at showdown\n */\n async muck(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"MUCK\" });\n }\n\n /**\n * Use time bank\n */\n async timeBank(tableId: string): Promise<PublicState> {\n return this.action(tableId, { type: \"TIME_BANK\" });\n }\n\n // ============================================================================\n // User\n // ============================================================================\n\n /**\n * Get current user profile and balances\n */\n async getProfile(): Promise<UserProfile> {\n return this.request<UserProfile>(\"GET\", \"/user/me\");\n }\n\n /**\n * Get hand history\n */\n async getHandHistory(): Promise<HandHistoryEntry[]> {\n const response = await this.request<{ history: HandHistoryEntry[] }>(\"GET\", \"/user/history\");\n return response.history;\n }\n\n /**\n * Request a withdrawal\n */\n async withdraw(request: WithdrawalRequest): Promise<{\n id: string;\n status: string;\n amount: number;\n destination: string;\n blockchain: string;\n token: string;\n }> {\n return this.request(\"POST\", \"/user/withdraw\", request);\n }\n\n /**\n * Get withdrawal history\n */\n async getWithdrawals(): Promise<WithdrawalRecord[]> {\n const response = await this.request<{ withdrawals: WithdrawalRecord[] }>(\n \"GET\",\n \"/user/withdrawals\"\n );\n return response.withdrawals;\n }\n\n // ============================================================================\n // Finance\n // ============================================================================\n\n /**\n * Get supported blockchains and tokens\n */\n async getChains(): Promise<BlockchainInfo[]> {\n return this.request<BlockchainInfo[]>(\"GET\", \"/finance/chains\");\n }\n\n /**\n * Start deposit monitoring session\n */\n async startDeposit(): Promise<DepositSession> {\n return this.request<DepositSession>(\"POST\", \"/finance/deposit/start\");\n }\n\n /**\n * Get deposit address\n */\n async getDepositAddress(): Promise<string> {\n const response = await this.request<{ address: string }>(\"GET\", \"/finance/deposit/address\");\n return response.address;\n }\n\n /**\n * Get deposit history\n */\n async getDeposits(): Promise<DepositRecord[]> {\n const response = await this.request<{ deposits: DepositRecord[] }>(\"GET\", \"/finance/deposits\");\n return response.deposits;\n }\n\n // ============================================================================\n // Notes\n // ============================================================================\n\n /**\n * Get all notes by current user\n */\n async getNotes(): Promise<PlayerNote[]> {\n const response = await this.request<{ notes: PlayerNote[] }>(\"GET\", \"/notes\");\n return response.notes;\n }\n\n /**\n * Get note for specific player\n */\n async getNote(targetId: string): Promise<PlayerNote | null> {\n const response = await this.request<{ note: PlayerNote | null }>(\"GET\", `/notes/${targetId}`);\n return response.note;\n }\n\n /**\n * Save or update note\n */\n async saveNote(targetId: string, content: string, label?: string): Promise<PlayerNote> {\n const response = await this.request<{ note: PlayerNote }>(\"POST\", \"/notes\", {\n targetId,\n content,\n label,\n });\n return response.note;\n }\n\n /**\n * Delete note\n */\n async deleteNote(targetId: string): Promise<void> {\n await this.request(\"DELETE\", `/notes/${targetId}`);\n }\n\n // ============================================================================\n // Health\n // ============================================================================\n\n /**\n * Health check\n */\n async health(): Promise<{ status: string; timestamp: number }> {\n return this.request(\"GET\", \"/health\");\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Make HTTP request with retry logic\n */\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this.token) {\n headers.Authorization = `Bearer ${this.token}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.retry.count; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n if (this.debug) {\n console.log(`[PokerSDK] ${method} ${path}`, body);\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle 304 Not Modified\n if (response.status === 304) {\n throw new PokerSDKError(\"Not Modified\", \"NOT_MODIFIED\", 304);\n }\n\n // Handle non-2xx responses\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n message?: string;\n error?: string;\n code?: string;\n };\n\n throw new PokerSDKError(\n errorData.message ?? errorData.error ?? `HTTP ${response.status}`,\n errorData.code ?? errorData.error ?? \"HTTP_ERROR\",\n response.status,\n errorData\n );\n }\n\n const data = (await response.json()) as T;\n\n if (this.debug) {\n console.log(`[PokerSDK] Response:`, data);\n }\n\n return data;\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry client errors (4xx) except rate limiting\n if (error instanceof PokerSDKError) {\n if (\n error.statusCode &&\n error.statusCode >= 400 &&\n error.statusCode < 500 &&\n error.statusCode !== 429\n ) {\n throw error;\n }\n }\n\n // Don't retry on abort\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PokerSDKError(\"Request timeout\", \"TIMEOUT\", undefined, {\n timeout: this.timeout,\n });\n }\n\n // Retry with backoff\n if (attempt < this.retry.count) {\n const delay = this.retry.delay * Math.pow(this.retry.backoff, attempt);\n if (this.debug) {\n console.log(`[PokerSDK] Retry ${attempt + 1}/${this.retry.count} in ${delay}ms`);\n }\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError ?? new PokerSDKError(\"Request failed\", \"REQUEST_FAILED\");\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * PokerSocket - WebSocket client for real-time game updates\n *\n * Provides automatic reconnection, heartbeat, and typed event handling\n * for real-time poker game state synchronization.\n */\n\nimport type {\n PublicState,\n ClientMessage,\n JoinTableMessage,\n LeaveTableMessage,\n PingMessage,\n} from \"@pokertools/types\";\n\nimport { safeParseServerMessage } from \"@pokertools/types\";\n\nimport {\n PokerSDKConfig,\n PokerSDKError,\n ConnectionState,\n PokerSocketEvents,\n EventListener,\n} from \"./types\";\n\n/**\n * WebSocket configuration\n */\ninterface SocketConfig {\n /** WebSocket URL */\n url: string;\n /** JWT token for authentication */\n token: string;\n /** Heartbeat interval in ms (default: 25000) */\n heartbeatInterval?: number;\n /** Reconnection attempts (default: 10) */\n reconnectAttempts?: number;\n /** Base reconnection delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Max reconnection delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n /** Custom WebSocket implementation */\n WebSocket?: typeof WebSocket;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Default socket configuration\n */\nconst DEFAULT_SOCKET_CONFIG = {\n heartbeatInterval: 25000,\n reconnectAttempts: 10,\n reconnectDelay: 1000,\n maxReconnectDelay: 30000,\n};\n\n/**\n * PokerSocket - Real-time WebSocket client\n *\n * @example\n * ```typescript\n * const socket = new PokerSocket({\n * url: \"wss://api.poker.example.com/ws/play\",\n * token: \"jwt-token\",\n * });\n *\n * // Listen for events\n * socket.on(\"connect\", () => console.log(\"Connected!\"));\n * socket.on(\"stateUpdate\", (tableId, state) => {\n * console.log(\"State updated:\", state);\n * });\n *\n * // Connect\n * await socket.connect();\n *\n * // Join a table\n * await socket.join(\"table-123\");\n *\n * // Later: disconnect\n * socket.disconnect();\n * ```\n */\nexport class PokerSocket {\n private readonly url: string;\n private readonly token: string;\n private readonly heartbeatInterval: number;\n private readonly reconnectAttempts: number;\n private readonly reconnectDelay: number;\n private readonly maxReconnectDelay: number;\n private readonly WebSocketImpl: typeof WebSocket;\n private readonly debug: boolean;\n\n private ws: WebSocket | null = null;\n private connectionState: ConnectionState = \"disconnected\";\n private reconnectCount = 0;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private pendingRequests = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n }\n >();\n private joinedTables = new Set<string>();\n private listeners = new Map<\n keyof PokerSocketEvents,\n Set<EventListener<keyof PokerSocketEvents>>\n >();\n private shouldReconnect = true;\n\n // Latest state cache for each table\n private stateCache = new Map<string, PublicState>();\n\n // Version metadata per table (exposed safely via getTableVersion)\n private tableVersions = new Map<string, number>();\n\n constructor(config: SocketConfig) {\n // Construct WebSocket URL with token\n const wsUrl = new URL(config.url);\n wsUrl.searchParams.set(\"token\", config.token);\n this.url = wsUrl.toString();\n this.token = config.token;\n\n this.heartbeatInterval = config.heartbeatInterval ?? DEFAULT_SOCKET_CONFIG.heartbeatInterval;\n this.reconnectAttempts = config.reconnectAttempts ?? DEFAULT_SOCKET_CONFIG.reconnectAttempts;\n this.reconnectDelay = config.reconnectDelay ?? DEFAULT_SOCKET_CONFIG.reconnectDelay;\n this.maxReconnectDelay = config.maxReconnectDelay ?? DEFAULT_SOCKET_CONFIG.maxReconnectDelay;\n this.WebSocketImpl = config.WebSocket ?? globalThis.WebSocket;\n this.debug = config.debug ?? false;\n }\n\n /**\n * Create a PokerSocket from SDK config\n */\n static fromConfig(config: PokerSDKConfig): PokerSocket {\n if (!config.token) {\n throw new PokerSDKError(\"Token is required for WebSocket connection\", \"AUTH_REQUIRED\");\n }\n\n const baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n const wsUrl = config.wsUrl ?? baseUrl.replace(/^http/, \"ws\") + \"/ws/play\";\n\n return new PokerSocket({\n url: wsUrl,\n token: config.token,\n WebSocket: config.WebSocket,\n debug: config.debug,\n });\n }\n\n // ============================================================================\n // Connection Management\n // ============================================================================\n\n /**\n * Connect to the WebSocket server\n */\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.connectionState === \"connected\") {\n resolve();\n return;\n }\n\n if (this.connectionState === \"connecting\") {\n // Wait for existing connection attempt\n const checkConnection = () => {\n if (this.connectionState === \"connected\") {\n resolve();\n } else if (this.connectionState === \"disconnected\") {\n reject(new PokerSDKError(\"Connection failed\", \"CONNECTION_FAILED\"));\n } else {\n setTimeout(checkConnection, 100);\n }\n };\n checkConnection();\n return;\n }\n\n this.shouldReconnect = true;\n this.connectionState = \"connecting\";\n this.log(\"Connecting to\", this.url);\n\n try {\n this.ws = new this.WebSocketImpl(this.url);\n\n this.ws.onopen = () => {\n this.connectionState = \"connected\";\n this.reconnectCount = 0;\n this.startHeartbeat();\n this.emit(\"connect\");\n this.log(\"Connected\");\n\n // Rejoin previously joined tables\n void this.rejoinTables();\n\n resolve();\n };\n\n this.ws.onclose = (event) => {\n this.handleDisconnect(event.reason || \"Connection closed\");\n };\n\n this.ws.onerror = (event) => {\n this.log(\"WebSocket error:\", event);\n if (this.connectionState === \"connecting\") {\n reject(new PokerSDKError(\"Connection failed\", \"CONNECTION_FAILED\"));\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data as string);\n };\n } catch (error) {\n this.connectionState = \"disconnected\";\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n this.shouldReconnect = false;\n this.stopHeartbeat();\n this.clearPendingRequests(\"Connection closed\");\n\n if (this.ws) {\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.connectionState = \"disconnected\";\n this.emit(\"disconnect\", \"Client disconnect\");\n this.log(\"Disconnected\");\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.connectionState;\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connectionState === \"connected\";\n }\n\n // ============================================================================\n // Table Subscription\n // ============================================================================\n\n /**\n * Join a table to receive real-time updates\n */\n async join(tableId: string): Promise<PublicState> {\n if (this.connectionState !== \"connected\") {\n throw new PokerSDKError(\"Not connected\", \"NOT_CONNECTED\");\n }\n\n const requestId = this.generateRequestId();\n const message: JoinTableMessage = {\n type: \"JOIN\",\n tableId,\n requestId,\n };\n\n this.joinedTables.add(tableId);\n this.send(message);\n\n // Wait for snapshot response\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new PokerSDKError(\"Join timeout\", \"TIMEOUT\"));\n }, 10000);\n\n // Store resolver for snapshot message\n this.pendingRequests.set(`snapshot:${tableId}`, {\n resolve: (state) => {\n clearTimeout(timeout);\n resolve(state as PublicState);\n },\n reject,\n timeout,\n });\n });\n }\n\n /**\n * Leave a table\n */\n leave(tableId: string): void {\n if (this.connectionState !== \"connected\") {\n return;\n }\n\n this.joinedTables.delete(tableId);\n this.stateCache.delete(tableId);\n this.tableVersions.delete(tableId);\n\n const message: LeaveTableMessage = {\n type: \"LEAVE\",\n tableId,\n };\n\n this.send(message);\n }\n\n /**\n * Get currently joined tables\n */\n getJoinedTables(): string[] {\n return Array.from(this.joinedTables);\n }\n\n /**\n * Get cached state for a table\n */\n getCachedState(tableId: string): PublicState | undefined {\n return this.stateCache.get(tableId);\n }\n\n /**\n * Get latest known version for a table\n * Returns undefined if no version has been received\n */\n getTableVersion(tableId: string): number | undefined {\n return this.tableVersions.get(tableId);\n }\n\n // ============================================================================\n // Event Handling\n // ============================================================================\n\n /**\n * Subscribe to an event\n */\n on<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n off<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener);\n }\n }\n\n /**\n * Subscribe to an event (once)\n */\n once<E extends keyof PokerSocketEvents>(event: E, listener: PokerSocketEvents[E]): () => void {\n const onceWrapper = ((...args: Parameters<PokerSocketEvents[E]>) => {\n this.off(event, onceWrapper);\n (listener as (...args: unknown[]) => void)(...args);\n }) as PokerSocketEvents[E];\n\n return this.on(event, onceWrapper);\n }\n\n // ============================================================================\n // Ping\n // ============================================================================\n\n /**\n * Send application-level ping (not WebSocket ping)\n */\n async ping(): Promise<number> {\n if (this.connectionState !== \"connected\") {\n throw new PokerSDKError(\"Not connected\", \"NOT_CONNECTED\");\n }\n\n const requestId = this.generateRequestId();\n const startTime = Date.now();\n\n const message: PingMessage = {\n type: \"PING\",\n requestId,\n timestamp: startTime,\n };\n\n this.send(message);\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new PokerSDKError(\"Ping timeout\", \"TIMEOUT\"));\n }, 5000);\n\n this.pendingRequests.set(requestId, {\n resolve: () => {\n resolve(Date.now() - startTime);\n },\n reject,\n timeout,\n });\n });\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Send a message to the server\n */\n private send(message: ClientMessage): void {\n if (this.ws?.readyState !== this.WebSocketImpl.OPEN) {\n throw new PokerSDKError(\"WebSocket not open\", \"NOT_CONNECTED\");\n }\n\n this.log(\"Sending:\", message);\n this.ws.send(JSON.stringify(message));\n }\n\n /**\n * Handle incoming message\n */\n private handleMessage(data: string): void {\n try {\n const parsed: unknown = JSON.parse(data);\n const result = safeParseServerMessage(parsed);\n if (!result.success) {\n this.log(\"Invalid server message:\", result.error);\n return;\n }\n const message = result.data;\n this.log(\"Received:\", message);\n\n switch (message.type) {\n case \"SNAPSHOT\": {\n // Cache state and track version\n this.stateCache.set(message.tableId, message.state);\n this.tableVersions.set(message.tableId, message.version);\n\n // Resolve pending join request\n const pending = this.pendingRequests.get(`snapshot:${message.tableId}`);\n if (pending) {\n this.pendingRequests.delete(`snapshot:${message.tableId}`);\n pending.resolve(message.state);\n }\n\n this.emit(\"snapshot\", message.tableId, message.state);\n break;\n }\n\n case \"STATE_UPDATE\": {\n // Track version metadata (always available)\n this.tableVersions.set(message.tableId, message.version);\n\n // Only emit if we have a cached state (from a prior SNAPSHOT)\n // Never emit a phantom partial PublicState\n const cachedState = this.stateCache.get(message.tableId);\n if (cachedState) {\n // Update version in cache to keep it consistent\n const updatedState = { ...cachedState, version: message.version };\n this.stateCache.set(message.tableId, updatedState);\n this.emit(\"stateUpdate\", message.tableId, updatedState);\n }\n // If no cached state, consumer should fetch via REST\n // Version is still available via getTableVersion()\n break;\n }\n\n case \"ACTION\": {\n this.emit(\n \"action\",\n message.tableId,\n message.playerId,\n message.actionType,\n message.amount\n );\n break;\n }\n\n case \"ACK\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.resolve(undefined);\n }\n break;\n }\n\n case \"PONG\": {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.resolve(message.timestamp);\n }\n break;\n }\n\n case \"ERROR\": {\n this.log(\"Server error:\", message);\n if (message.requestId) {\n const pending = this.pendingRequests.get(message.requestId);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(message.requestId);\n pending.reject(new PokerSDKError(message.message, message.code));\n }\n }\n this.emit(\"error\", new PokerSDKError(message.message, message.code));\n break;\n }\n }\n } catch (error) {\n this.log(\"Failed to parse message:\", error);\n }\n }\n\n /**\n * Handle disconnect\n */\n private handleDisconnect(reason: string): void {\n this.stopHeartbeat();\n this.ws = null;\n\n const wasConnected = this.connectionState === \"connected\";\n this.connectionState = \"disconnected\";\n\n if (wasConnected) {\n this.emit(\"disconnect\", reason);\n }\n\n // Attempt reconnection if enabled\n if (this.shouldReconnect && this.reconnectCount < this.reconnectAttempts) {\n void this.reconnect();\n }\n }\n\n /**\n * Attempt to reconnect\n */\n private async reconnect(): Promise<void> {\n this.reconnectCount++;\n this.connectionState = \"reconnecting\";\n\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectCount - 1),\n this.maxReconnectDelay\n );\n\n this.log(\n `Reconnecting in ${delay}ms (attempt ${this.reconnectCount}/${this.reconnectAttempts})`\n );\n this.emit(\"reconnect\", this.reconnectCount);\n\n await this.sleep(delay);\n\n if (!this.shouldReconnect) {\n return;\n }\n\n try {\n await this.connect();\n } catch {\n // connect() handles its own errors\n }\n }\n\n /**\n * Rejoin previously joined tables\n */\n private async rejoinTables(): Promise<void> {\n for (const tableId of this.joinedTables) {\n try {\n await this.join(tableId);\n } catch (error) {\n this.log(\"Failed to rejoin table:\", tableId, error);\n }\n }\n }\n\n /**\n * Start heartbeat timer\n */\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n if (this.connectionState === \"connected\") {\n void this.ping().catch(() => {\n // Ping failed, connection might be dead\n this.log(\"Heartbeat failed\");\n });\n }\n }, this.heartbeatInterval);\n }\n\n /**\n * Stop heartbeat timer\n */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n /**\n * Clear all pending requests\n */\n private clearPendingRequests(reason: string): void {\n for (const pending of this.pendingRequests.values()) {\n clearTimeout(pending.timeout);\n\n pending.reject(new PokerSDKError(reason, \"CONNECTION_CLOSED\"));\n }\n this.pendingRequests.clear();\n }\n\n /**\n * Emit event to listeners\n */\n private emit<E extends keyof PokerSocketEvents>(\n event: E,\n ...args: Parameters<PokerSocketEvents[E]>\n ): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n for (const listener of listeners) {\n try {\n (listener as (...args: unknown[]) => void)(...args);\n } catch (error) {\n this.log(\"Listener error:\", error);\n }\n }\n }\n }\n\n /**\n * Generate unique request ID\n */\n private generateRequestId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Debug logger\n */\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log(\"[PokerSocket]\", ...args);\n }\n }\n}\n","/**\n * Authentication helpers for SIWE (Sign-In with Ethereum)\n *\n * These utilities help construct SIWE messages for wallet signing.\n */\n\n/**\n * SIWE message parameters\n */\nexport interface SiweMessageParams {\n /** Domain making the request (e.g., \"poker.example.com\") */\n domain: string;\n /** Ethereum address (checksummed) */\n address: string;\n /** Human-readable statement (optional) */\n statement?: string;\n /** URI of the signing resource */\n uri: string;\n /** Current version of the message (always \"1\") */\n version?: \"1\";\n /** Chain ID */\n chainId?: number;\n /** Nonce from server */\n nonce: string;\n /** Issued at timestamp (ISO 8601) */\n issuedAt?: string;\n /** Expiration time (ISO 8601) */\n expirationTime?: string;\n /** Not before time (ISO 8601) */\n notBefore?: string;\n /** Request ID */\n requestId?: string;\n /** Resources (URIs) */\n resources?: string[];\n}\n\n/**\n * Create a SIWE message string for signing\n *\n * @example\n * ```typescript\n * import { createSiweMessage } from \"@pokertools/sdk\";\n *\n * // Get nonce from server\n * const nonce = await client.getNonce();\n *\n * // Create message\n * const message = createSiweMessage({\n * domain: \"poker.example.com\",\n * address: \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n * uri: \"https://poker.example.com\",\n * nonce,\n * statement: \"Sign in to PokerTools\",\n * });\n *\n * // Sign with wallet (e.g., wagmi, ethers, viem)\n * const signature = await signMessage({ message });\n *\n * // Login\n * const { token, user } = await client.login({ message, signature });\n * ```\n */\nexport function createSiweMessage(params: SiweMessageParams): string {\n const {\n domain,\n address,\n statement,\n uri,\n version = \"1\",\n chainId = 1,\n nonce,\n issuedAt = new Date().toISOString(),\n expirationTime,\n notBefore,\n requestId,\n resources,\n } = params;\n\n // Build message following EIP-4361 spec\n const lines: string[] = [];\n\n // Header\n lines.push(`${domain} wants you to sign in with your Ethereum account:`);\n lines.push(address);\n\n // Statement (optional)\n if (statement) {\n lines.push(\"\");\n lines.push(statement);\n }\n\n // Required fields\n lines.push(\"\");\n lines.push(`URI: ${uri}`);\n lines.push(`Version: ${version}`);\n lines.push(`Chain ID: ${chainId}`);\n lines.push(`Nonce: ${nonce}`);\n lines.push(`Issued At: ${issuedAt}`);\n\n // Optional fields\n if (expirationTime) {\n lines.push(`Expiration Time: ${expirationTime}`);\n }\n if (notBefore) {\n lines.push(`Not Before: ${notBefore}`);\n }\n if (requestId) {\n lines.push(`Request ID: ${requestId}`);\n }\n if (resources && resources.length > 0) {\n lines.push(`Resources:`);\n for (const resource of resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Parse a SIWE message string back into params\n */\nexport function parseSiweMessage(message: string): Partial<SiweMessageParams> {\n const lines = message.split(\"\\n\");\n const result: Partial<SiweMessageParams> = {};\n\n // First line: domain\n const domainMatch = /^(.+) wants you to sign in with your Ethereum account:$/.exec(lines[0]);\n if (domainMatch) {\n result.domain = domainMatch[1];\n }\n\n // Second line: address\n if (lines[1]) {\n result.address = lines[1];\n }\n\n // Parse key-value pairs\n for (const line of lines) {\n if (line.startsWith(\"URI: \")) {\n result.uri = line.slice(5);\n } else if (line.startsWith(\"Version: \")) {\n result.version = line.slice(9) as \"1\";\n } else if (line.startsWith(\"Chain ID: \")) {\n result.chainId = parseInt(line.slice(10), 10);\n } else if (line.startsWith(\"Nonce: \")) {\n result.nonce = line.slice(7);\n } else if (line.startsWith(\"Issued At: \")) {\n result.issuedAt = line.slice(11);\n } else if (line.startsWith(\"Expiration Time: \")) {\n result.expirationTime = line.slice(17);\n } else if (line.startsWith(\"Not Before: \")) {\n result.notBefore = line.slice(12);\n } else if (line.startsWith(\"Request ID: \")) {\n result.requestId = line.slice(12);\n }\n }\n\n // Parse statement (lines between address and URI)\n const uriIndex = lines.findIndex((l) => l.startsWith(\"URI: \"));\n if (uriIndex > 3) {\n const statementLines = lines.slice(3, uriIndex - 1).filter((l) => l.trim());\n if (statementLines.length > 0) {\n result.statement = statementLines.join(\"\\n\");\n }\n }\n\n return result;\n}\n\n/**\n * Check if a SIWE message is expired\n */\nexport function isSiweExpired(message: string): boolean {\n const parsed = parseSiweMessage(message);\n if (!parsed.expirationTime) {\n return false;\n }\n return new Date(parsed.expirationTime) < new Date();\n}\n\n/**\n * Create a withdrawal message for signing\n *\n * Includes nonce and timestamp to prevent replay attacks.\n *\n * @param amount - Amount in USD\n * @param destinationAddress - Destination Ethereum address\n * @param nonce - Unique nonce to prevent replay (recommended: use generateIdempotencyKey())\n * @param timestamp - Unix timestamp in milliseconds (defaults to now)\n *\n * @example\n * ```typescript\n * const nonce = generateIdempotencyKey();\n * const message = createWithdrawalMessage(100, \"0x...\", nonce);\n * const signature = await signMessage({ message });\n * await client.withdraw({\n * amount: 100, address: \"0x...\", blockchainId, tokenId,\n * message, signature, idempotencyKey: nonce\n * });\n * ```\n */\nexport function createWithdrawalMessage(\n amount: number,\n destinationAddress: string,\n nonce: string,\n timestamp?: number\n): string {\n const ts = timestamp ?? Date.now();\n const baseMsg = `Withdraw ${amount} USD to ${destinationAddress}`;\n return `${baseMsg}\\nNonce: ${nonce}\\nTimestamp: ${ts}`;\n}\n\n/**\n * Generate a random idempotency key\n * Uses crypto.randomUUID if available, otherwise falls back to timestamp + random\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}-${Math.random().toString(36).substr(2, 9)}`;\n}\n","/**\n * Utility functions for the PokerTools SDK\n */\n\nimport type { PublicState, PublicPlayer } from \"@pokertools/types\";\n\n/**\n * Format chip amount to display string\n * @param chips - Amount in cents (1 chip = 1 cent)\n * @param currency - Currency symbol (default: \"$\")\n */\nexport function formatChips(chips: number, currency = \"$\"): string {\n const dollars = chips / 100;\n return `${currency}${dollars.toFixed(2)}`;\n}\n\n/**\n * Parse display amount to chips (cents)\n * @param amount - Display amount string (e.g., \"$10.50\", \"10.50\", \"1050\")\n */\nexport function parseChips(amount: string): number {\n // Remove currency symbols and whitespace\n const cleaned = amount.replace(/[$€£¥,\\s]/g, \"\");\n const value = parseFloat(cleaned);\n\n if (isNaN(value)) {\n throw new Error(`Invalid amount: ${amount}`);\n }\n\n // If it looks like it's already in cents (integer), return as-is\n if (Number.isInteger(value) && value >= 100) {\n return value;\n }\n\n // Otherwise, convert from dollars to cents\n return Math.round(value * 100);\n}\n\n/**\n * Get the player whose turn it is\n */\nexport function getActivePlayer(state: PublicState): PublicPlayer | null {\n if (state.actionTo === null) {\n return null;\n }\n return state.players[state.actionTo] ?? null;\n}\n\n/**\n * Get player by ID\n */\nexport function getPlayerById(state: PublicState, playerId: string): PublicPlayer | null {\n return state.players.find((p) => p?.id === playerId) ?? null;\n}\n\n/**\n * Get player seat index by ID\n */\nexport function getPlayerSeat(state: PublicState, playerId: string): number | null {\n const index = state.players.findIndex((p) => p?.id === playerId);\n return index === -1 ? null : index;\n}\n\n/**\n * Check if it's a specific player's turn\n */\nexport function isPlayerTurn(state: PublicState, playerId: string): boolean {\n if (state.actionTo === null) {\n return false;\n }\n const player = state.players[state.actionTo];\n return player?.id === playerId;\n}\n\n/**\n * Get the amount needed to call\n */\nexport function getCallAmount(state: PublicState, playerId: string): number {\n const player = getPlayerById(state, playerId);\n if (!player) {\n return 0;\n }\n\n const currentBet = player.betThisStreet;\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return Math.min(highestBet - currentBet, player.stack);\n}\n\n/**\n * Get minimum raise amount\n */\nexport function getMinRaise(state: PublicState): number {\n return state.minRaise ?? state.config.bigBlind;\n}\n\n/**\n * Check if player can check\n */\nexport function canCheck(state: PublicState, playerId: string): boolean {\n const player = getPlayerById(state, playerId);\n if (!player || !isPlayerTurn(state, playerId)) {\n return false;\n }\n\n const currentBet = player.betThisStreet;\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return currentBet >= highestBet;\n}\n\n/**\n * Check if player can bet (no prior bets this round)\n */\nexport function canBet(state: PublicState, playerId: string): boolean {\n const player = getPlayerById(state, playerId);\n if (!player || !isPlayerTurn(state, playerId)) {\n return false;\n }\n\n const activePlayers = state.players.filter((p): p is PublicPlayer => p !== null);\n const bets = activePlayers.map((p) => p.betThisStreet);\n\n const highestBet = Math.max(...bets);\n\n return highestBet === 0 && player.stack > 0;\n}\n\n/**\n * Get total pot size (main pot + side pots)\n */\nexport function getTotalPot(state: PublicState): number {\n return state.pots.reduce((sum, pot) => sum + pot.amount, 0);\n}\n\n/**\n * Get number of active players (not folded, has chips)\n */\nexport function getActivePlayers(state: PublicState): PublicPlayer[] {\n return state.players.filter(\n (p): p is PublicPlayer => p !== null && p.status !== \"FOLDED\" && p.stack > 0\n );\n}\n\n/**\n * Get number of players in hand (not folded)\n */\nexport function getPlayersInHand(state: PublicState): PublicPlayer[] {\n return state.players.filter((p): p is PublicPlayer => p !== null && p.status !== \"FOLDED\");\n}\n\n/**\n * Card suit to emoji\n */\nexport function suitToEmoji(suit: string): string {\n const suits: Record<string, string> = {\n s: \"♠\",\n h: \"♥\",\n d: \"♦\",\n c: \"♣\",\n };\n return suits[suit.toLowerCase()] ?? suit;\n}\n\n/**\n * Format card for display (e.g., \"As\" -> \"A♠\")\n */\nexport function formatCard(card: string): string {\n if (card.length !== 2) {\n return card;\n }\n const rank = card[0].toUpperCase();\n const suit = suitToEmoji(card[1]);\n return `${rank}${suit}`;\n}\n\n/**\n * Format card array for display\n */\nexport function formatCards(cards: Array<string | null> | null): string {\n if (!cards) {\n return \"🂠🂠\";\n }\n return cards.map((c) => (c ? formatCard(c) : \"🂠\")).join(\" \");\n}\n\n/**\n * Get street display name\n */\nexport function getStreetName(street: string): string {\n const names: Record<string, string> = {\n PREFLOP: \"Pre-Flop\",\n FLOP: \"Flop\",\n TURN: \"Turn\",\n RIVER: \"River\",\n SHOWDOWN: \"Showdown\",\n };\n return names[street] ?? street;\n}\n\n/**\n * Check if game is in showdown phase\n */\nexport function isShowdown(state: PublicState): boolean {\n return state.street === \"SHOWDOWN\";\n}\n\n/**\n * Check if hand is complete (has winners)\n */\nexport function isHandComplete(state: PublicState): boolean {\n return state.winners !== undefined && state.winners !== null;\n}\n\n/**\n * Calculate pot odds as a ratio\n */\nexport function getPotOdds(state: PublicState, playerId: string): number {\n const callAmount = getCallAmount(state, playerId);\n if (callAmount === 0) {\n return Infinity;\n }\n return getTotalPot(state) / callAmount;\n}\n\n/**\n * Abbreviate large numbers (e.g., 1000 -> \"1K\")\n */\nexport function abbreviateNumber(num: number): string {\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1)}M`;\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1)}K`;\n }\n return num.toString();\n}\n"]}
@@ -406,6 +406,8 @@ var PokerSocket = class _PokerSocket {
406
406
  this.shouldReconnect = true;
407
407
  // Latest state cache for each table
408
408
  this.stateCache = /* @__PURE__ */ new Map();
409
+ // Version metadata per table (exposed safely via getTableVersion)
410
+ this.tableVersions = /* @__PURE__ */ new Map();
409
411
  const wsUrl = new URL(config.url);
410
412
  wsUrl.searchParams.set("token", config.token);
411
413
  this.url = wsUrl.toString();
@@ -559,6 +561,7 @@ var PokerSocket = class _PokerSocket {
559
561
  }
560
562
  this.joinedTables.delete(tableId);
561
563
  this.stateCache.delete(tableId);
564
+ this.tableVersions.delete(tableId);
562
565
  const message = {
563
566
  type: "LEAVE",
564
567
  tableId
@@ -577,6 +580,13 @@ var PokerSocket = class _PokerSocket {
577
580
  getCachedState(tableId) {
578
581
  return this.stateCache.get(tableId);
579
582
  }
583
+ /**
584
+ * Get latest known version for a table
585
+ * Returns undefined if no version has been received
586
+ */
587
+ getTableVersion(tableId) {
588
+ return this.tableVersions.get(tableId);
589
+ }
580
590
  // ============================================================================
581
591
  // Event Handling
582
592
  // ============================================================================
@@ -672,6 +682,7 @@ var PokerSocket = class _PokerSocket {
672
682
  switch (message.type) {
673
683
  case "SNAPSHOT": {
674
684
  this.stateCache.set(message.tableId, message.state);
685
+ this.tableVersions.set(message.tableId, message.version);
675
686
  const pending = this.pendingRequests.get(`snapshot:${message.tableId}`);
676
687
  if (pending) {
677
688
  this.pendingRequests.delete(`snapshot:${message.tableId}`);
@@ -681,15 +692,12 @@ var PokerSocket = class _PokerSocket {
681
692
  break;
682
693
  }
683
694
  case "STATE_UPDATE": {
695
+ this.tableVersions.set(message.tableId, message.version);
684
696
  const cachedState = this.stateCache.get(message.tableId);
685
697
  if (cachedState) {
686
698
  const updatedState = { ...cachedState, version: message.version };
687
699
  this.stateCache.set(message.tableId, updatedState);
688
700
  this.emit("stateUpdate", message.tableId, updatedState);
689
- } else {
690
- this.emit("stateUpdate", message.tableId, {
691
- version: message.version
692
- });
693
701
  }
694
702
  break;
695
703
  }