@pokertools/sdk 1.0.11 โ†’ 1.0.16

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/README.md CHANGED
@@ -1,14 +1,35 @@
1
- # @pokertools/sdk
1
+ # ๐Ÿƒ @pokertools/sdk
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@pokertools/sdk)](https://www.npmjs.com/package/@pokertools/sdk)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
6
  The official TypeScript SDK for the **PokerTools** platform. Build real-time Texas Hold'em applications with ease, featuring robust state management, WebSocket integration, and React hooks.
7
7
 
8
+ ## Table of Contents
9
+
10
+ - [โœจ Features](#-features)
11
+ - [๐Ÿ“ฆ Installation](#-installation)
12
+ - [๐Ÿš€ Quick Start (React)](#-quick-start-react)
13
+ - [๐Ÿ—๏ธ Architecture](#๏ธ-architecture)
14
+ - [๐Ÿ”‘ Authentication (SIWE)](#-authentication-siwe)
15
+ - [๐Ÿ“ก Real-time Events](#-real-time-events)
16
+ - [๐Ÿ› ๏ธ Configuration](#๏ธ-configuration)
17
+ - [๐Ÿ”ด Error Handling](#-error-handling)
18
+ - [๐Ÿ› ๏ธ API Reference](#๏ธ-api-reference)
19
+ - [React Hooks](#react-hooks)
20
+ - [PokerClient (REST API)](#pokerclient-rest-api)
21
+ - [PokerSocket (WebSocket)](#pokersocket-websocket)
22
+ - [Auth Helpers (SIWE)](#auth-helpers-siwe)
23
+ - [Utilities](#utilities)
24
+ - [Main Exports](#main-exports)
25
+ - [๐Ÿงช Testing](#-testing)
26
+ - [๐Ÿ“ฆ Related Packages](#-related-packages)
27
+ - [๐Ÿ“„ License](#-license)
28
+
8
29
  ## โœจ Features
9
30
 
10
31
  - ๐Ÿ”Œ **Real-time WebSocket Client**: Automatic reconnection, heartbeats, and typed events. JWTs are sent as WebSocket subprotocol credentials (not in the URL query string) to avoid leaking tokens in access logs.
11
- - ๐ŸŽฃ **React Hooks**: `PokerProvider`, `usePoker`, `usePokerClient`, `usePokerSocket`, `useTable`, `useUser`, `useTables`, `useConnection` for seamless UI integration.
32
+ - ๐ŸŽฃ **React Hooks**: `PokerProvider`, `usePoker`, `usePokerClient`, `usePokerSocket`, `useTable`, `useUser`, `useTables`, `useTournaments`, `useTournament`, `useConnection` for seamless UI integration.
12
33
  - ๐Ÿ” **Authentication**: Built-in support for Sign-In with Ethereum (SIWE), nonce/lifecycle helpers, and replay-safe withdrawal message generation.
13
34
  - ๐Ÿ›ก๏ธ **Type-Safe**: Full TypeScript support with shared types re-exported from `@pokertools/types`.
14
35
  - ๐Ÿ”„ **State Management**: Automatic synchronization of game state (snapshots + delta updates) with version-tracking and conditional fetching.
@@ -24,7 +45,7 @@ yarn add @pokertools/sdk @pokertools/types
24
45
  pnpm add @pokertools/sdk @pokertools/types
25
46
  ```
26
47
 
27
- `@pokertools/sdk` (v1.0.11) depends on `@pokertools/types` (v1.0.11) for shared TypeScript types.
48
+ `@pokertools/sdk` (v1.0.16) depends on `@pokertools/types` (v1.0.16) for shared TypeScript types.
28
49
  The React hooks require `react >= 19.2.3` as an **optional** peer dependency โ€” install `react`
29
50
  and `react-dom` only if you plan to use the React integration.
30
51
 
@@ -159,12 +180,14 @@ The SDK bridges your frontend application with the PokerTools API and Real-time
159
180
 
160
181
  | Component | Description |
161
182
  | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162
- | `PokerClient` | Handles REST API requests (Tables, User, Finance, Notes, Health). Auto-retry with exponential backoff. |
183
+ | `PokerClient` | Handles REST API requests (Tables, Tournaments, User, Finance, Notes, Health). Auto-retry with exponential backoff. |
163
184
  | `PokerSocket` | Manages WebSocket connection, auto-reconnection, heartbeats, and typed real-time events. |
164
185
  | `PokerProvider` | React Context provider that initializes the client and socket. Accepts `autoConnect` prop (default `true`) to automatically connect the WebSocket when a token is present. |
165
186
  | `useTable` | Hook that subscribes to a specific table's real-time updates via WebSocket (snapshots + deltas). |
166
187
  | `useUser` | Hook to fetch and manage the current user's profile and balances. |
167
188
  | `useTables` | Hook to fetch the list of active tables from the REST API. |
189
+ | `useTournaments` | Hook to fetch active and registering tournament lobbies from the REST API. |
190
+ | `useTournament` | Hook to fetch one tournament's entries, table assignments, blind structure, and payout configuration. |
168
191
  | `usePoker` | Low-level hook to access the full `PokerContextValue` (client, socket, connection state). |
169
192
  | `usePokerClient` | Convenience hook to get the `PokerClient` instance. |
170
193
  | `usePokerSocket` | Convenience hook to get the `PokerSocket` instance (null if not connected). |
@@ -276,6 +299,89 @@ socket.leave("table-1");
276
299
  socket.disconnect();
277
300
  ```
278
301
 
302
+ ## ๐Ÿ› ๏ธ Configuration
303
+
304
+ All configuration flows through two main interfaces: `PokerSDKConfig` (for the REST client and SDK initialization) and the `PokerSocket` constructor options (for WebSocket-specific settings).
305
+
306
+ ### PokerSDKConfig
307
+
308
+ Used by `new PokerClient(config)`, `new PokerSocket(config)`, and `<PokerProvider config={...}>`.
309
+
310
+ | Option | Type | Default | Description |
311
+ | ----------- | ------------------ | --------------------------------------- | ------------------------------------------------------- |
312
+ | `baseUrl` | `string` | โ€” **(required)** | API base URL (e.g., `"https://api.poker.example.com"`). |
313
+ | `wsUrl` | `string` | baseUrl with `ws://` | WebSocket server URL. |
314
+ | `token` | `string` | `undefined` | JWT token for authentication. |
315
+ | `timeout` | `number` | `30000` | Request timeout in milliseconds. |
316
+ | `retry` | `RetryConfig` | `{ count: 3, delay: 1000, backoff: 2 }` | Retry configuration. |
317
+ | `fetch` | `typeof fetch` | `globalThis.fetch` | Custom fetch implementation (e.g., for React Native). |
318
+ | `WebSocket` | `typeof WebSocket` | `globalThis.WebSocket` | Custom WebSocket implementation. |
319
+ | `debug` | `boolean` | `false` | Enable request/response debug logging. |
320
+
321
+ ### PokerSocket Constructor Options
322
+
323
+ When constructing a `PokerSocket` directly (non-React):
324
+
325
+ | Option | Type | Default | Description |
326
+ | ------------------- | ------------------ | ---------------------- | ------------------------------------- |
327
+ | `url` | `string` | โ€” **(required)** | WebSocket server URL. |
328
+ | `token` | `string` | โ€” **(required)** | JWT for subprotocol authentication. |
329
+ | `heartbeatInterval` | `number` | `25000` | Application-level ping interval (ms). |
330
+ | `reconnectAttempts` | `number` | `10` | Max reconnection attempts. |
331
+ | `reconnectDelay` | `number` | `1000` | Base reconnection delay (ms). |
332
+ | `maxReconnectDelay` | `number` | `30000` | Max reconnection delay (ms). |
333
+ | `WebSocket` | `typeof WebSocket` | `globalThis.WebSocket` | Custom WebSocket implementation. |
334
+ | `debug` | `boolean` | `false` | Enable debug logging. |
335
+
336
+ Static factory: `PokerSocket.fromConfig(config: PokerSDKConfig)` creates a socket from a full SDK config object.
337
+
338
+ ## ๐Ÿ”ด Error Handling
339
+
340
+ ### PokerSDKError
341
+
342
+ All SDK errors are thrown as `PokerSDKError` instances, which extend the standard `Error` class with additional metadata:
343
+
344
+ ```typescript
345
+ import { PokerSDKError } from "@pokertools/sdk";
346
+
347
+ try {
348
+ await client.buyIn("table-1", { amount: 500, seat: 3 });
349
+ } catch (error) {
350
+ if (error instanceof PokerSDKError) {
351
+ console.log("Code:", error.code); // e.g., "NOT_MODIFIED", "VALIDATION_ERROR"
352
+ console.log("Status:", error.statusCode); // e.g., 304, 400, 429, 500
353
+ console.log("Details:", error.details); // Server-provided error details
354
+ }
355
+ }
356
+ ```
357
+
358
+ Common error codes:
359
+
360
+ - `NOT_MODIFIED` (304) โ€” State unchanged; returned by `getTableState()` when the version matches the `since` parameter.
361
+ - `TIMEOUT` โ€” Request exceeded the configured timeout.
362
+ - `REQUEST_FAILED` โ€” Network failure or max retries exhausted.
363
+
364
+ ### Retry Behavior
365
+
366
+ `PokerClient` automatically retries failed requests using exponential backoff:
367
+
368
+ 1. **Retries**: Up to `3` attempts by default (configurable via `retry.count`).
369
+ 2. **Backoff**: Each retry waits `delay ร— backoff^attempt` ms (default: `1000ms ร— 2^n`).
370
+ 3. **Retryable errors**: 5xx server errors, network failures, and rate-limited (429) responses.
371
+ 4. **Non-retryable errors**: 4xx client errors (except 429) and aborted requests are not retried.
372
+
373
+ ### Debug Logging
374
+
375
+ Set `debug: true` on `PokerSDKConfig` to enable verbose console output:
376
+
377
+ ```
378
+ [PokerSDK] GET https://api.example.com/tables
379
+ [PokerSDK] Response 200 (45ms)
380
+ [PokerSDK] Retry 2/3 in 2000ms
381
+ ```
382
+
383
+ This is useful during development for tracing request lifecycle and retry behavior.
384
+
279
385
  ## ๐Ÿ› ๏ธ API Reference
280
386
 
281
387
  ### React Hooks
@@ -313,13 +419,13 @@ Returns the `PokerSocket` instance (or `null` if not connected).
313
419
 
314
420
  Returns:
315
421
 
316
- | Field | Type | Description |
317
- | ----------- | ---------------------- | ----------------------------------------------------------------- |
318
- | `profile` | `UserProfile \| null` | Full profile including `username`, `address`, `role`, `balances`. |
319
- | `balances` | `UserBalances \| null` | `{ main: number, inPlay: number }` in cents. |
320
- | `isLoading` | `boolean` | Initial fetch in progress. |
321
- | `error` | `Error \| null` | Fetch error if any. |
322
- | `refresh()` | `() => Promise<void>` | Re-fetch profile from API. |
422
+ | Field | Type | Description |
423
+ | ----------- | ---------------------- | ----------------------------------------------------------------------- |
424
+ | `profile` | `UserProfile \| null` | Full profile including `username`, `address`, `role`, `balances`. |
425
+ | `balances` | `UserBalances \| null` | `{ main: number; inPlay: number; pendingWithdrawal: number }` in cents. |
426
+ | `isLoading` | `boolean` | Initial fetch in progress. |
427
+ | `error` | `Error \| null` | Fetch error if any. |
428
+ | `refresh()` | `() => Promise<void>` | Re-fetch profile from API. |
323
429
 
324
430
  #### `useTable(tableId, options?)`
325
431
 
@@ -395,20 +501,28 @@ interface PokerSDKConfig {
395
501
 
396
502
  #### Methods
397
503
 
398
- | Method | Description |
399
- | --------------------------- | ----------------------------------------------------------------------- |
400
- | `setToken(token)` | Update or clear the JWT. |
401
- | `getToken()` | Get current token. |
402
- | `isAuthenticated()` | Check if token is present. |
403
- | `health()` | `GET /health` โ€” health check. |
404
- | `getNonce()` | `POST /auth/nonce` โ€” get SIWE nonce. |
405
- | `login(request)` | `POST /auth/login` โ€” complete SIWE auth. |
406
- | `logout()` | `POST /auth/logout` โ€” revoke session. |
407
- | `getTables()` | `GET /tables` โ€” list active tables. |
408
- | `createTable(config)` | `POST /tables` โ€” create a new table. Returns `tableId`. |
409
- | `getTableState(id, since?)` | `GET /tables/:id` โ€” fetch state; returns `null` (via 304) if unchanged. |
410
- | `buyIn(tableId, request)` | `POST /tables/:id/buy-in` โ€” join a table. |
411
- | `action(tableId, request)` | `POST /tables/:id/action` โ€” execute game action. |
504
+ | Method | Description |
505
+ | --------------------------------- | ----------------------------------------------------------------------- |
506
+ | `setToken(token)` | Update or clear the JWT. |
507
+ | `getToken()` | Get current token. |
508
+ | `isAuthenticated()` | Check if token is present. |
509
+ | `health()` | `GET /health` โ€” health check. |
510
+ | `getNonce()` | `POST /auth/nonce` โ€” get SIWE nonce. |
511
+ | `login(request)` | `POST /auth/login` โ€” complete SIWE auth. |
512
+ | `logout()` | `POST /auth/logout` โ€” revoke session. |
513
+ | `getTables()` | `GET /tables` โ€” list active tables. |
514
+ | `createTable(config)` | `POST /tables` โ€” create a new table. Returns `tableId`. |
515
+ | `getTableState(id, since?)` | `GET /tables/:id` โ€” fetch state; returns `null` (via 304) if unchanged. |
516
+ | `buyIn(tableId, request)` | `POST /tables/:id/buy-in` โ€” join a table. |
517
+ | `action(tableId, request)` | `POST /tables/:id/action` โ€” execute game action. |
518
+ | `getTournaments()` | `GET /tournaments` โ€” list registration and running tournaments. |
519
+ | `createTournament(request)` | `POST /tournaments` โ€” create a tournament lobby. |
520
+ | `getTournament(id)` | `GET /tournaments/:id` โ€” fetch entries, tables, and payout config. |
521
+ | `registerTournament(id, request)` | `POST /tournaments/:id/register` โ€” register and debit buy-in/fee. |
522
+ | `startTournament(id)` | `POST /tournaments/:id/start` โ€” start and receive table distribution. |
523
+ | `reconcileTournament(id)` | `POST /tournaments/:id/reconcile` โ€” run tournament-director balancing. |
524
+ | `advanceTournamentBlinds(id)` | `POST /tournaments/:id/advance-blinds` โ€” advance active table blinds. |
525
+ | `settleTournament(id)` | `POST /tournaments/:id/settle` โ€” pay configured prize distribution. |
412
526
 
413
527
  **Convenience action wrappers** (all return `Promise<PublicState>`):
414
528
 
@@ -556,27 +670,64 @@ Exported from `@pokertools/sdk` (25+ helpers for formatting, state inspection, a
556
670
 
557
671
  #### `@pokertools/sdk` (main entry)
558
672
 
559
- | Export | Kind |
560
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
561
- | `PokerClient` | Class |
562
- | `PokerSocket` | Class |
563
- | `createSiweMessage`, `parseSiweMessage`, `isSiweExpired`, `createWithdrawalMessage`, `generateIdempotencyKey` | Function |
564
- | `SiweMessageParams` | Type |
565
- | `formatChips`, `parseChips`, `getActivePlayer`, `getPlayerById`, `getPlayerSeat`, `isPlayerTurn`, `getCallAmount`, `getMinRaise`, `canCheck`, `canBet`, `getTotalPot`, `getActivePlayers`, `getPlayersInHand`, `suitToEmoji`, `formatCard`, `formatCards`, `getStreetName`, `isShowdown`, `isHandComplete`, `getPotOdds`, `abbreviateNumber` | Function |
566
- | `PokerSDKConfig`, `UserBalances`, `UserProfile`, `BlockchainInfo`, `TokenInfo`, `DepositSession`, `DepositRecord`, `WithdrawalRequest`, `WithdrawalRecord`, `HandHistoryEntry`, `PlayerNote`, `ConnectionState`, `PokerSocketEvents`, `EventListener` | Type |
567
- | `PokerSDKError` | Class |
568
- | `PublicState`, `PublicPlayer`, `GameState`, `Player`, `Action`, `ActionType`, `TableConfig`, `ServerMessage`, `ClientMessage`, `SnapshotMessage`, `StateUpdateMessage`, `ErrorMessage`, `JoinTableMessage`, `LeaveTableMessage`, `CreateTableRequest`, `BuyInRequest`, `AddChipsRequest`, `GameActionRequest`, `LoginRequest`, `LoginResponse`, `NonceResponse`, `TableListItem` | Type (re-exported from `@pokertools/types`) |
673
+ | Export | Kind |
674
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
675
+ | `PokerClient` | Class |
676
+ | `PokerSocket` | Class |
677
+ | `createSiweMessage`, `parseSiweMessage`, `isSiweExpired`, `createWithdrawalMessage`, `generateIdempotencyKey` | Function |
678
+ | `SiweMessageParams` | Type |
679
+ | `formatChips`, `parseChips`, `getActivePlayer`, `getPlayerById`, `getPlayerSeat`, `isPlayerTurn`, `getCallAmount`, `getMinRaise`, `canCheck`, `canBet`, `getTotalPot`, `getActivePlayers`, `getPlayersInHand`, `suitToEmoji`, `formatCard`, `formatCards`, `getStreetName`, `isShowdown`, `isHandComplete`, `getPotOdds`, `abbreviateNumber` | Function |
680
+ | `PokerSDKConfig`, `UserBalances`, `UserProfile`, `BlockchainInfo`, `TokenInfo`, `DepositSession`, `DepositRecord`, `WithdrawalRequest`, `WithdrawalRecord`, `HandHistoryEntry`, `PlayerNote`, `ConnectionState`, `PokerSocketEvents`, `EventListener` | Type |
681
+ | `PokerSDKError` | Class |
682
+ | `PublicState`, `PublicPlayer`, `GameState`, `Player`, `Action`, `ActionType`, `TableConfig`, `ServerMessage`, `ClientMessage`, `SnapshotMessage`, `StateUpdateMessage`, `ErrorMessage`, `JoinTableMessage`, `LeaveTableMessage`, `CreateTableRequest`, `BuyInRequest`, `AddChipsRequest`, `GameActionRequest`, `LoginRequest`, `LoginResponse`, `NonceResponse`, `TableListItem`, `TournamentListItem`, `TournamentDetails`, `StartTournamentResponse`, `ReconcileTournamentResponse`, `SettleTournamentResponse` | Type (re-exported from `@pokertools/types`) |
569
683
 
570
684
  #### `@pokertools/sdk/react` (React subpath)
571
685
 
572
- | Export | Kind |
573
- | --------------------------------------------------------------------------------------------------- | --------- |
574
- | `PokerProvider` | Component |
575
- | `PokerProviderProps` | Type |
576
- | `PokerContextValue` | Type |
577
- | `usePoker`, `usePokerClient`, `usePokerSocket`, `useTable`, `useUser`, `useTables`, `useConnection` | Hook |
578
- | `UseTableOptions`, `UseTableResult`, `UseUserResult`, `UseTablesResult` | Type |
686
+ | Export | Kind |
687
+ | -------------------------------------------------------------------------------------------------------------------------------------- | --------- |
688
+ | `PokerProvider` | Component |
689
+ | `PokerProviderProps` | Type |
690
+ | `PokerContextValue` | Type |
691
+ | `usePoker`, `usePokerClient`, `usePokerSocket`, `useTable`, `useUser`, `useTables`, `useTournaments`, `useTournament`, `useConnection` | Hook |
692
+ | `UseTableOptions`, `UseTableResult`, `UseUserResult`, `UseTablesResult` | Type |
579
693
 
580
694
  ---
581
695
 
582
- Made with โ™ฅ for the Poker Community.
696
+ ## ๐Ÿงช Testing
697
+
698
+ The SDK ships with a comprehensive test suite using [Vitest](https://vitest.dev/). Run all tests from the repository root:
699
+
700
+ ```bash
701
+ npm test -w @pokertools/sdk
702
+ ```
703
+
704
+ Or run them directly from the package directory:
705
+
706
+ ```bash
707
+ cd packages/sdk && npx vitest run
708
+ ```
709
+
710
+ The test suite comprises **7 test suites** covering:
711
+
712
+ | Suite | Description |
713
+ | --------------------------- | ---------------------------------------------------- |
714
+ | `auth.test.ts` | SIWE helpers: message creation, parsing, expiry. |
715
+ | `client.test.ts` | REST client: request lifecycle, retry, error paths. |
716
+ | `socket.test.ts` | WebSocket client: connect, events, reconnect logic. |
717
+ | `react.test.tsx` | React hooks: provider, state management, user data. |
718
+ | `edge-cases.test.ts` | Boundary conditions and error-handling scenarios. |
719
+ | `types-regressions.test.ts` | Type-level regression safety for exported types. |
720
+ | `utils.test.ts` | Formatting helpers, state inspection, display utils. |
721
+
722
+ ## ๐Ÿ”— Related Packages
723
+
724
+ | Package | Description |
725
+ | ------------------------------------- | -------------------------------------------- |
726
+ | [@pokertools/types](../types) | Shared TypeScript types and type guards. |
727
+ | [@pokertools/api](../api) | REST/WebSocket API (Fastify) |
728
+ | [@pokertools/engine](../engine) | Core game engine and state machine. |
729
+ | [@pokertools/evaluator](../evaluator) | High-performance lookup-table hand evaluator |
730
+
731
+ ## ๐Ÿ“„ License
732
+
733
+ MIT ยฉ A.Aurelius