@dimcool/sdk 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2629 @@
1
+ import { Transaction } from '@solana/web3.js';
2
+ import { RpsGameAction, RpsGameState, RpsAction } from '@dimcool/rps';
3
+ import { ChessGameAction, ChessGameState, ChessMovePayload } from '@dimcool/chess';
4
+ import { NimGameAction, NimGameState } from '@dimcool/nim';
5
+ import { DotsAndBoxesGameAction, DotsAndBoxesGameState } from '@dimcool/dots-and-boxes';
6
+ import { TicTacToeGameAction, TicTacToeGameState } from '@dimcool/tic-tac-toe';
7
+ import { Connect4GameAction, Connect4GameState } from '@dimcool/connect-four';
8
+ export { MICRO_UNITS, formatMoneyMinor, toMajor } from '@dimcool/utils';
9
+
10
+ /**
11
+ * Interface for HTTP client implementations.
12
+ * Allows for dependency injection and testing with custom implementations.
13
+ */
14
+ interface IHttpClient {
15
+ /**
16
+ * Make a generic HTTP request
17
+ */
18
+ request<T>(endpoint: string, options?: RequestInit): Promise<T>;
19
+ /**
20
+ * Make a GET request
21
+ */
22
+ get<T>(endpoint: string, options?: RequestInit): Promise<T>;
23
+ /**
24
+ * Make a POST request
25
+ */
26
+ post<T>(endpoint: string, data?: any, options?: RequestInit): Promise<T>;
27
+ /**
28
+ * Make a PATCH request
29
+ */
30
+ patch<T>(endpoint: string, data?: any, options?: RequestInit): Promise<T>;
31
+ /**
32
+ * Make a DELETE request
33
+ */
34
+ delete<T>(endpoint: string, options?: RequestInit): Promise<T>;
35
+ /**
36
+ * Upload a file using FormData
37
+ */
38
+ upload<T>(endpoint: string, formData: FormData): Promise<T>;
39
+ }
40
+
41
+ declare const TOKEN_KEY = "dim_sdk_token";
42
+ interface IStorage {
43
+ set(key: string, value: string): void;
44
+ get(key: string): string | null;
45
+ delete(key: string): void;
46
+ }
47
+ declare class BrowserLocalStorage implements IStorage {
48
+ set(key: string, value: string): void;
49
+ get(key: string): string | null;
50
+ delete(key: string): void;
51
+ }
52
+ declare class NodeStorage implements IStorage {
53
+ private storage;
54
+ private readonly instanceId;
55
+ constructor();
56
+ set(key: string, value: string): void;
57
+ get(key: string): string | null;
58
+ delete(key: string): void;
59
+ /**
60
+ * Get the instance ID for debugging/verification
61
+ * @internal
62
+ */
63
+ getInstanceId(): string;
64
+ }
65
+
66
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
67
+ interface ILogger {
68
+ debug(message: string, ...args: any[]): void;
69
+ info(message: string, ...args: any[]): void;
70
+ warn(message: string, ...args: any[]): void;
71
+ error(message: string, ...args: any[]): void;
72
+ }
73
+ declare class Logger implements ILogger {
74
+ private level;
75
+ private prefix;
76
+ constructor(prefix?: string);
77
+ setLevel(level: LogLevel): void;
78
+ getLevel(): LogLevel;
79
+ private shouldLog;
80
+ private formatMessage;
81
+ debug(message: string, ...args: any[]): void;
82
+ info(message: string, ...args: any[]): void;
83
+ warn(message: string, ...args: any[]): void;
84
+ error(message: string, ...args: any[]): void;
85
+ }
86
+ declare const logger: Logger;
87
+ declare const createLogger: (prefix: string) => Logger;
88
+
89
+ type WsEventHandler = (payload: unknown) => void;
90
+ type WsWildcardHandler = (event: string, payload: unknown) => void;
91
+ interface WsTransport {
92
+ connect(): void;
93
+ disconnect(): void;
94
+ setAccessToken(token: string): void;
95
+ clearAccessToken(): void;
96
+ setAppId(appId: string): void;
97
+ waitUntilConnected(timeoutMs?: number): Promise<void>;
98
+ getConnectionState(): ConnectionState;
99
+ resetRooms(): void;
100
+ subscribeEvent(eventName: string, handler: WsEventHandler): () => void;
101
+ subscribeAll(handler: WsWildcardHandler): () => void;
102
+ joinRoom(roomName: string): () => void;
103
+ emit(eventName: string, payload?: unknown): void;
104
+ }
105
+ interface ConnectionState {
106
+ connected: boolean;
107
+ connecting: boolean;
108
+ error: string | null;
109
+ }
110
+
111
+ interface SDKConfig {
112
+ appId: string;
113
+ baseUrl?: string;
114
+ storage: IStorage;
115
+ httpClient?: IHttpClient;
116
+ wsTransport?: WsTransport;
117
+ logger?: ILogger;
118
+ }
119
+ type MoneyMinor = number;
120
+ interface LoginResponse {
121
+ access_token: string;
122
+ user: {
123
+ id: string;
124
+ email: string | null;
125
+ username?: string | null;
126
+ isAdmin: boolean;
127
+ avatar?: string;
128
+ coverImage?: string;
129
+ bio?: string;
130
+ chessElo: number;
131
+ points: number;
132
+ };
133
+ }
134
+ interface GenerateHandshakeResponse {
135
+ message: string;
136
+ nonce: string;
137
+ }
138
+ /**
139
+ * Metadata about the wallet used for authentication.
140
+ * Used to track which wallet provider was used for login.
141
+ */
142
+ interface WalletMeta {
143
+ /** The type of wallet connection */
144
+ type: 'phantom-embedded' | 'keypair';
145
+ /** The OAuth/connection provider (for phantom-embedded) */
146
+ provider?: 'google' | 'apple' | 'injected';
147
+ /** The name of the wallet (e.g., 'phantom', 'solflare') */
148
+ walletName?: string;
149
+ }
150
+ interface User {
151
+ id: string;
152
+ email: string | null;
153
+ username?: string | null;
154
+ isAdmin: boolean;
155
+ avatar?: string;
156
+ coverImage?: string;
157
+ bio?: string;
158
+ chessElo: number;
159
+ points: number;
160
+ createdAt: string;
161
+ updatedAt: string;
162
+ banned?: boolean;
163
+ bannedAt?: string;
164
+ bannedReason?: string;
165
+ loginAddress?: string | null;
166
+ }
167
+ interface PaginatedUsers {
168
+ users: User[];
169
+ total: number;
170
+ page: number;
171
+ limit: number;
172
+ totalPages: number;
173
+ }
174
+ interface FeatureFlag {
175
+ id: string;
176
+ name: string;
177
+ enabled: boolean;
178
+ createdAt: string;
179
+ updatedAt: string;
180
+ }
181
+ interface ApiError {
182
+ error?: string;
183
+ message?: string | string[];
184
+ statusCode?: number;
185
+ code?: string;
186
+ }
187
+ interface UsernameAvailabilityResponse {
188
+ valid: boolean;
189
+ available: boolean;
190
+ }
191
+ interface PublicUser {
192
+ id: string;
193
+ username?: string;
194
+ avatar?: string;
195
+ coverImage?: string;
196
+ bio?: string;
197
+ chessElo: number;
198
+ points: number;
199
+ connectedStatus: 'online' | 'away' | 'offline';
200
+ lastConnectedAt?: string;
201
+ createdAt: string;
202
+ updatedAt: string;
203
+ friendsCount: number;
204
+ friendshipStatus?: 'none' | 'incoming' | 'outgoing' | 'friends';
205
+ /** Number of unique users currently spectating this user. Only present on profile / game views. */
206
+ spectatorCount?: number;
207
+ }
208
+ interface PaginatedFriends {
209
+ friends: PublicUser[];
210
+ total: number;
211
+ page: number;
212
+ limit: number;
213
+ totalPages: number;
214
+ }
215
+ interface SearchUser {
216
+ id: string;
217
+ username?: string;
218
+ avatar?: string;
219
+ chessElo: number;
220
+ connectedStatus: 'online' | 'away' | 'offline';
221
+ lastConnectedAt?: string;
222
+ createdAt: string;
223
+ updatedAt: string;
224
+ friendshipStatus?: 'none' | 'incoming' | 'outgoing' | 'friends';
225
+ walletAddress?: string;
226
+ }
227
+ interface FriendRequestItem {
228
+ id: string;
229
+ user: PublicUser;
230
+ mutualFriendsCount: number;
231
+ createdAt: string;
232
+ }
233
+ interface PaginatedSearchUsers {
234
+ users: SearchUser[];
235
+ total: number;
236
+ page: number;
237
+ limit: number;
238
+ totalPages: number;
239
+ }
240
+ interface Session {
241
+ id: string;
242
+ userId: string;
243
+ loginMethod: 'email' | 'wallet';
244
+ walletMeta?: WalletMeta;
245
+ timestamp: string;
246
+ user?: {
247
+ id: string;
248
+ email: string | null;
249
+ username: string | null;
250
+ isAdmin: boolean;
251
+ avatar?: string;
252
+ };
253
+ }
254
+ interface PaginatedSessions {
255
+ sessions: Session[];
256
+ total: number;
257
+ }
258
+ type ActivityFeedItemType = 'new_user' | 'win' | 'lobby_created' | 'game_started';
259
+ interface ActivityFeedUser {
260
+ id: string;
261
+ username: string;
262
+ avatarUrl?: string;
263
+ }
264
+ interface ActivityFeedItem {
265
+ id: string;
266
+ type: ActivityFeedItemType;
267
+ user: ActivityFeedUser;
268
+ opponent?: ActivityFeedUser;
269
+ game?: string;
270
+ amount?: number;
271
+ timestamp: number;
272
+ }
273
+ interface ActivityFeedResponse {
274
+ items: ActivityFeedItem[];
275
+ }
276
+ interface LeaderboardEntry {
277
+ rank: number;
278
+ userId: string;
279
+ username: string;
280
+ avatar?: string;
281
+ wins: number;
282
+ losses: number;
283
+ winRate: number;
284
+ gameEarnings: MoneyMinor;
285
+ referralEarnings: MoneyMinor;
286
+ earnings: MoneyMinor;
287
+ }
288
+ interface LeaderboardResponse {
289
+ entries: LeaderboardEntry[];
290
+ generatedAt: string;
291
+ }
292
+ interface LeaderboardQuery {
293
+ startDate?: string;
294
+ endDate?: string;
295
+ limit?: number;
296
+ }
297
+ type LeaderboardRange = LeaderboardQuery;
298
+ interface CurrentGame {
299
+ gameId: string;
300
+ gameType: string;
301
+ status: string;
302
+ }
303
+ /** User activity for spectate flow. GET /users/:userId/activity */
304
+ type UserActivityStatus = 'in_game' | 'in_lobby' | 'idle';
305
+ interface UserActivity {
306
+ status: UserActivityStatus;
307
+ gameId?: string;
308
+ gameType?: string;
309
+ lobbyId?: string;
310
+ lobbyStatus?: string;
311
+ }
312
+ interface GameHistoryItem {
313
+ id: string;
314
+ gameType: string;
315
+ gameName: string;
316
+ gameImage?: string;
317
+ result: 'win' | 'loss' | 'draw';
318
+ betAmount: MoneyMinor;
319
+ winnings?: MoneyMinor;
320
+ opponent?: {
321
+ id: string;
322
+ username?: string;
323
+ avatar?: string;
324
+ };
325
+ playedAt: string;
326
+ depositTransactionHashes?: string[];
327
+ payoutTransactionHash?: string;
328
+ }
329
+ interface UserStats {
330
+ gamesPlayed: number;
331
+ wins: number;
332
+ losses: number;
333
+ totalEarned: MoneyMinor;
334
+ referralEarned: MoneyMinor;
335
+ totalLost: MoneyMinor;
336
+ totalFeesPaid: MoneyMinor;
337
+ chessElo: number;
338
+ points: number;
339
+ marketOrdersPlaced: number;
340
+ }
341
+ interface AdminStats {
342
+ /** Fee payer wallet public key (base58), when configured. */
343
+ feePayerWalletAddress: string | null;
344
+ /** Escrow wallet public key (base58), when configured. */
345
+ escrowWalletAddress: string | null;
346
+ totalGamesPlayed: number;
347
+ totalFeesGenerated: MoneyMinor;
348
+ totalFeesPaid: MoneyMinor;
349
+ totalFeesUnpaid: MoneyMinor;
350
+ totalVolume: MoneyMinor;
351
+ totalUsers: number;
352
+ totalFriendships: number;
353
+ pendingFriendRequests: number;
354
+ /** Total confirmed P2P transfers. */
355
+ totalTransferCount: number;
356
+ /** Aggregate USDC fees collected from P2P transfers (minor units). */
357
+ totalTransferFeesUsdc: MoneyMinor;
358
+ /** Aggregate SOL fees collected from P2P transfers (lamports). */
359
+ totalTransferFeesSol: number;
360
+ /** Fee payer wallet SOL balance (float, SOL). */
361
+ feePayerSolBalance: number;
362
+ /** Fee payer wallet USDC balance (minor units). */
363
+ feePayerUsdcBalance: number;
364
+ /** Escrow wallet SOL balance (float, SOL). */
365
+ escrowSolBalance: number;
366
+ /** Escrow wallet USDC balance (minor units). */
367
+ escrowUsdcBalance: MoneyMinor;
368
+ /** Total unsettled liabilities reserved in escrow (minor units). */
369
+ escrowLiabilitiesUsdc: MoneyMinor;
370
+ /** Total accrued fees according to accounting sources (minor units). */
371
+ accruedFeesUsdc: MoneyMinor;
372
+ /** Configured reserve buffer that cannot be swept (minor units). */
373
+ reserveBufferUsdc: MoneyMinor;
374
+ /** Maximum safe sweepable amount right now (minor units). */
375
+ maxSweepableUsdc: MoneyMinor;
376
+ /** Last successful sweep amount (minor units). */
377
+ lastSweepAmountUsdc: MoneyMinor;
378
+ /** Last successful sweep tx hash. */
379
+ lastSweepTxHash: string | null;
380
+ /** Last successful sweep confirmation time. */
381
+ lastSweepAt: string | null;
382
+ /** Total ATAs funded by the fee payer. */
383
+ totalAtasFunded: number;
384
+ /** Estimated total cost of funded ATAs (lamports). */
385
+ estimatedAtaCostLamports: number;
386
+ /** Total prediction markets created. */
387
+ totalMarkets: number;
388
+ /** Total volume traded across all prediction markets (minor units). */
389
+ totalMarketVolume: MoneyMinor;
390
+ /** Total fees collected from prediction markets (minor units). */
391
+ totalMarketFees: MoneyMinor;
392
+ }
393
+ interface EscrowSweepPreview {
394
+ escrowSolBalance: number;
395
+ escrowUsdcBalance: MoneyMinor;
396
+ accruedFeesUsdc: MoneyMinor;
397
+ reserveBufferUsdc: MoneyMinor;
398
+ maxSweepableUsdc: MoneyMinor;
399
+ liabilities: Record<string, MoneyMinor>;
400
+ }
401
+ interface EscrowSweepRecord {
402
+ id: string;
403
+ requestedByUserId: string;
404
+ requestedAmount: MoneyMinor;
405
+ approvedAmount: MoneyMinor;
406
+ destinationAddress: string;
407
+ txHash: string | null;
408
+ status: 'PENDING' | 'CONFIRMED' | 'FAILED';
409
+ errorMessage: string | null;
410
+ createdAt: string;
411
+ confirmedAt: string | null;
412
+ failedAt: string | null;
413
+ }
414
+ type CriticalIncidentSeverity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
415
+ type CriticalIncidentStatus = 'OPEN' | 'ACKNOWLEDGED' | 'RESOLVED';
416
+ type CriticalIncidentImpactType = 'FUNDS_LOSS' | 'FUNDS_LOCKED' | 'UNAUTHORIZED_TRANSFER' | 'ACCOUNTING_MISMATCH';
417
+ type CriticalIncidentCategory = 'GAME_PAYOUT_FAILED' | 'BET_PAYOUT_FAILED' | 'ESCROW_SWEEP_FAILED' | 'ESCROW_SWEEP_STUCK' | 'REFUND_FAILED' | 'TRANSFER_AUTH_MISMATCH' | 'DEPOSIT_OWNERSHIP_MISMATCH' | 'TRANSACTION_STUCK' | 'RECONCILIATION_MISMATCH';
418
+ interface CriticalIncident {
419
+ id: string;
420
+ fingerprint: string;
421
+ category: CriticalIncidentCategory;
422
+ severity: CriticalIncidentSeverity;
423
+ status: CriticalIncidentStatus;
424
+ impactType: CriticalIncidentImpactType;
425
+ source: string;
426
+ sourceKey?: string | null;
427
+ title: string;
428
+ description: string;
429
+ amountMinor?: MoneyMinor | null;
430
+ currencyMint?: string | null;
431
+ walletTransactionSignature?: string | null;
432
+ relatedSignature?: string | null;
433
+ gameHistoryId?: string | null;
434
+ marketId?: string | null;
435
+ lobbyId?: string | null;
436
+ userId?: string | null;
437
+ escrowSweepId?: string | null;
438
+ retryCount: number;
439
+ lastError?: string | null;
440
+ lastEscalatedAt?: string | null;
441
+ escalationAttempts: number;
442
+ lastEscalationError?: string | null;
443
+ detectedAt: string;
444
+ resolvedAt?: string | null;
445
+ createdAt: string;
446
+ updatedAt: string;
447
+ }
448
+ interface CriticalIncidentSummary {
449
+ openCritical: number;
450
+ openHigh: number;
451
+ openTotal: number;
452
+ impactedAmountMinor: MoneyMinor;
453
+ freshest: CriticalIncident[];
454
+ }
455
+ interface PaginatedCriticalIncidents {
456
+ items: CriticalIncident[];
457
+ total: number;
458
+ page: number;
459
+ limit: number;
460
+ totalPages: number;
461
+ }
462
+ interface AdminDailyStatsItem {
463
+ date: string;
464
+ gamesPlayed: number;
465
+ platformFees: MoneyMinor;
466
+ referralFees: MoneyMinor;
467
+ bettingFees: MoneyMinor;
468
+ marketFees: MoneyMinor;
469
+ }
470
+ interface AdminDailyStats {
471
+ days: AdminDailyStatsItem[];
472
+ }
473
+ interface ReferralSummary {
474
+ code: string | null;
475
+ link?: string;
476
+ hasReferrer: boolean;
477
+ totals: {
478
+ level1: MoneyMinor;
479
+ level2: MoneyMinor;
480
+ level3: MoneyMinor;
481
+ };
482
+ earnings: {
483
+ pending: MoneyMinor;
484
+ claimed: MoneyMinor;
485
+ };
486
+ }
487
+ interface ApplyReferralCodeResponse {
488
+ success: boolean;
489
+ referrerUsername: string;
490
+ }
491
+ interface ReferralTreeItem {
492
+ id: string;
493
+ username?: string | null;
494
+ createdAt: string;
495
+ }
496
+ interface ReferralTreeResponse {
497
+ level: 1 | 2 | 3;
498
+ items: ReferralTreeItem[];
499
+ nextCursor?: string;
500
+ }
501
+ type ReferralRewardStatus = 'PENDING' | 'CLAIMED' | 'CANCELLED';
502
+ interface ReferralRewardItem {
503
+ id: string;
504
+ referredUserId: string;
505
+ referredUsername?: string | null;
506
+ gameHistoryId: string;
507
+ level: number;
508
+ amount: MoneyMinor;
509
+ status: ReferralRewardStatus;
510
+ createdAt: string;
511
+ claimedAt?: string;
512
+ }
513
+ interface ReferralRewardsResponse {
514
+ items: ReferralRewardItem[];
515
+ nextCursor?: string;
516
+ }
517
+ interface ClaimReferralRewardsResponse {
518
+ claimedCount: number;
519
+ claimedAmount: MoneyMinor;
520
+ walletTransactionSignature?: string;
521
+ }
522
+ type ReportStatus = 'PENDING' | 'READ' | 'RESOLVED' | 'DISMISSED';
523
+ interface ReportUser {
524
+ id: string;
525
+ username?: string;
526
+ avatar?: string;
527
+ }
528
+ interface Report {
529
+ id: string;
530
+ reporterId: string;
531
+ reportedUserId: string;
532
+ reason: string;
533
+ status: ReportStatus;
534
+ adminNotes?: string;
535
+ createdAt: string;
536
+ updatedAt: string;
537
+ reporter?: ReportUser;
538
+ reportedUser?: ReportUser;
539
+ }
540
+ interface PaginatedReports {
541
+ reports: Report[];
542
+ total: number;
543
+ page: number;
544
+ limit: number;
545
+ totalPages: number;
546
+ }
547
+ interface ReportCount {
548
+ count: number;
549
+ }
550
+ type SupportTicketStatus = 'OPEN' | 'IN_PROGRESS' | 'WAITING_REPLY' | 'RESOLVED' | 'CLOSED';
551
+ type SupportTicketCategory = 'BUG' | 'FEATURE_REQUEST' | 'QUESTION' | 'ACCOUNT' | 'PAYMENT' | 'GAME' | 'TECHNICAL' | 'OTHER';
552
+ type SupportTicketPriority = 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
553
+ type SupportMessageSenderRole = 'USER' | 'ADMIN';
554
+ interface SupportTicketUser {
555
+ id: string;
556
+ username?: string;
557
+ avatar?: string;
558
+ }
559
+ interface SupportMessage {
560
+ id: string;
561
+ ticketId: string;
562
+ senderId: string;
563
+ senderRole: SupportMessageSenderRole;
564
+ content: string;
565
+ createdAt: string;
566
+ sender?: SupportTicketUser;
567
+ }
568
+ interface SupportTicket {
569
+ id: string;
570
+ userId: string;
571
+ subject: string;
572
+ category: SupportTicketCategory;
573
+ status: SupportTicketStatus;
574
+ priority: SupportTicketPriority;
575
+ createdAt: string;
576
+ updatedAt: string;
577
+ user?: SupportTicketUser;
578
+ messages?: SupportMessage[];
579
+ messageCount?: number;
580
+ }
581
+ interface PaginatedSupportTickets {
582
+ tickets: SupportTicket[];
583
+ total: number;
584
+ page: number;
585
+ limit: number;
586
+ totalPages: number;
587
+ }
588
+ type AppNotificationType = 'challenge_received' | 'challenge_accepted' | 'challenge_declined' | 'friend_request' | 'friend_accepted' | 'game_invite' | 'game_result' | 'achievement' | 'system' | 'usd_received';
589
+ interface AppNotification {
590
+ id: string;
591
+ type: AppNotificationType;
592
+ title: string;
593
+ message: string;
594
+ read: boolean;
595
+ fromUserId?: string;
596
+ fromUsername?: string;
597
+ avatar?: string;
598
+ actionPayload?: Record<string, unknown>;
599
+ createdAt: string;
600
+ }
601
+ interface PaginatedNotificationsResponse {
602
+ notifications: AppNotification[];
603
+ total: number;
604
+ page: number;
605
+ limit: number;
606
+ unreadCount: number;
607
+ }
608
+ interface Achievement {
609
+ id: string;
610
+ code: string;
611
+ name: string;
612
+ description: string | null;
613
+ category: string | null;
614
+ icon: string | null;
615
+ }
616
+ interface UserAchievement {
617
+ achievementId: string;
618
+ code: string;
619
+ name: string;
620
+ description: string | null;
621
+ icon: string | null;
622
+ unlockedAt: string;
623
+ }
624
+
625
+ interface WalletResponse {
626
+ publicKey: string;
627
+ }
628
+ /**
629
+ * Interface for wallet signing operations.
630
+ * Allows plugging in different signing implementations (e.g., Phantom, Keypair).
631
+ */
632
+ interface WalletSigner {
633
+ /**
634
+ * Optional wallet address used by auth flows that require address resolution.
635
+ * Example: Solana base58 public key.
636
+ */
637
+ address?: string;
638
+ /**
639
+ * Sign a message and return the signature
640
+ * @param message - The message to sign (typically a string)
641
+ * @returns The signature as Uint8Array or base64 string
642
+ */
643
+ signMessage: (message: string) => Promise<Uint8Array | string>;
644
+ /**
645
+ * Sign a transaction
646
+ * @param transaction - The Solana transaction to sign
647
+ * @returns The signed transaction
648
+ */
649
+ signTransaction: (transaction: Transaction) => Promise<Transaction>;
650
+ }
651
+ interface BalanceResponse {
652
+ sol: number;
653
+ usdc: MoneyMinor;
654
+ publicKey: string;
655
+ }
656
+ type WalletActivityKind = 'DEPOSIT' | 'REFUND' | 'PAYOUT' | 'TRANSFER';
657
+ type WalletActivityStatus = 'SIGNED' | 'CONFIRMED' | 'FAILED' | 'MISSING';
658
+ type WalletActivityDirection = 'IN' | 'OUT';
659
+ type WalletActivityCounterpartyType = 'USER' | 'GAME' | 'LOBBY' | 'SYSTEM';
660
+ type WalletClaimAction = {
661
+ type: 'lobby_deposit_refund';
662
+ lobbyId: string;
663
+ depositSignature: string;
664
+ } | {
665
+ type: 'game_payout';
666
+ gameHistoryId: string;
667
+ gameId: string;
668
+ } | {
669
+ type: 'referral_rewards_claim';
670
+ };
671
+ interface WalletActivityItem {
672
+ id: string;
673
+ signature?: string;
674
+ kind: WalletActivityKind;
675
+ status: WalletActivityStatus;
676
+ direction: WalletActivityDirection;
677
+ amount: MoneyMinor;
678
+ mint: string;
679
+ createdAt: string;
680
+ confirmedAt?: string;
681
+ context: {
682
+ type?: 'LOBBY' | 'GAME' | 'REFERRAL' | 'P2P';
683
+ id?: string;
684
+ };
685
+ counterparty: {
686
+ type: WalletActivityCounterpartyType;
687
+ username?: string;
688
+ id?: string;
689
+ };
690
+ claimable: boolean;
691
+ claimAction?: WalletClaimAction;
692
+ displayTitle?: string;
693
+ displaySubtitle?: string;
694
+ }
695
+ interface WalletActivityResponse {
696
+ items: WalletActivityItem[];
697
+ nextCursor?: string;
698
+ }
699
+ /** Admin only: one row per transaction with from/to user identification. */
700
+ interface AdminWalletActivityItem {
701
+ id: string;
702
+ signature?: string;
703
+ kind: WalletActivityKind;
704
+ status: WalletActivityStatus;
705
+ direction: WalletActivityDirection;
706
+ amount: MoneyMinor;
707
+ mint: string;
708
+ createdAt: string;
709
+ confirmedAt?: string;
710
+ context: {
711
+ type?: 'LOBBY' | 'GAME' | 'REFERRAL' | 'P2P';
712
+ id?: string;
713
+ };
714
+ counterparty: {
715
+ type: WalletActivityCounterpartyType;
716
+ username?: string;
717
+ id?: string;
718
+ };
719
+ displayTitle?: string;
720
+ displaySubtitle?: string;
721
+ fromUserId?: string;
722
+ toUserId?: string;
723
+ fromUsername?: string;
724
+ toUsername?: string;
725
+ }
726
+ interface AdminWalletActivityResponse {
727
+ items: AdminWalletActivityItem[];
728
+ nextCursor?: string;
729
+ }
730
+ interface FaucetResponse {
731
+ solTransactionHash: string;
732
+ usdcTransactionHash: string;
733
+ solAmount: number;
734
+ usdcAmount: MoneyMinor;
735
+ }
736
+ type TransferToken = 'USDC' | 'SOL';
737
+ declare const TRANSFER_FEE_MINOR = 10000;
738
+ declare const MIN_TRANSFER_AMOUNT = 50000;
739
+ declare const MIN_SOL_TRANSFER_AMOUNT = 1000000;
740
+ declare const SOL_DECIMALS = 9;
741
+ declare const SOL_MINT = "SOL";
742
+ declare const ESTIMATED_SOL_FEE_LAMPORTS = 10000;
743
+ interface PrepareTransferRequest {
744
+ senderAddress: string;
745
+ recipient: string;
746
+ amount: number;
747
+ token?: TransferToken;
748
+ }
749
+ interface PrepareTransferResponse {
750
+ transaction: string;
751
+ fee: number;
752
+ totalAmount: number;
753
+ recipientAddress: string;
754
+ token: TransferToken;
755
+ ataCreated?: boolean;
756
+ }
757
+ interface SubmitTransferRequest {
758
+ signedTransaction: string;
759
+ senderAddress: string;
760
+ recipientAddress: string;
761
+ amount: number;
762
+ token?: TransferToken;
763
+ ataCreated?: boolean;
764
+ recipientInput?: string;
765
+ }
766
+ interface SubmitTransferResponse {
767
+ signature: string;
768
+ status: 'confirmed' | 'pending';
769
+ }
770
+ interface SendTransferResponse extends SubmitTransferResponse {
771
+ recipientAddress: string;
772
+ fee: number;
773
+ totalAmount: number;
774
+ token: TransferToken;
775
+ ataCreated?: boolean;
776
+ }
777
+ declare class Wallet {
778
+ private http;
779
+ private logger;
780
+ private signer;
781
+ private walletData;
782
+ constructor(http: IHttpClient, logger?: ILogger);
783
+ /**
784
+ * Set the signer to use for signing operations.
785
+ * This should be called before any signing operations.
786
+ * @param signer - The signer implementation (e.g., Phantom wallet)
787
+ */
788
+ setSigner(signer: WalletSigner): void;
789
+ /**
790
+ * Clear the signer (e.g. on logout so the next session can register a different wallet).
791
+ */
792
+ clearSigner(): void;
793
+ /**
794
+ * Check if a signer has been configured
795
+ */
796
+ hasSigner(): boolean;
797
+ /**
798
+ * Return signer address if available.
799
+ */
800
+ getSignerAddress(): string | null;
801
+ /**
802
+ * Load wallet data from API
803
+ */
804
+ loadWallet(): Promise<WalletResponse>;
805
+ /**
806
+ * Sign a message using the configured signer
807
+ * @param message - The message to sign
808
+ * @returns The signature
809
+ */
810
+ signMessage(message: string): Promise<Uint8Array | string>;
811
+ /**
812
+ * Sign a transaction using the configured signer
813
+ * @param transaction - The transaction to sign
814
+ * @returns The signed transaction
815
+ */
816
+ signTransaction(transaction: Transaction): Promise<Transaction>;
817
+ /**
818
+ * Get SOL and USDC balances
819
+ */
820
+ getBalances(): Promise<BalanceResponse>;
821
+ getActivity(params?: {
822
+ limit?: number;
823
+ cursor?: string;
824
+ kinds?: WalletActivityKind[];
825
+ }): Promise<WalletActivityResponse>;
826
+ getUserActivity(userId: string, params?: {
827
+ limit?: number;
828
+ cursor?: string;
829
+ kinds?: WalletActivityKind[];
830
+ }): Promise<WalletActivityResponse>;
831
+ /**
832
+ * Get paginated wallet activity across all users (admin only).
833
+ * Optional filters: kinds, userId. Sort by date (asc/desc).
834
+ */
835
+ getAdminActivity(params?: {
836
+ limit?: number;
837
+ cursor?: string;
838
+ kinds?: WalletActivityKind[];
839
+ userId?: string;
840
+ sortOrder?: 'asc' | 'desc';
841
+ }): Promise<AdminWalletActivityResponse>;
842
+ /**
843
+ * Request test funds from faucet (development only)
844
+ * Sends 10 USDC and 0.05 SOL to the user's wallet
845
+ */
846
+ requestFaucet(): Promise<FaucetResponse>;
847
+ /**
848
+ * Prepare a transfer transaction (USDC or SOL)
849
+ * This is an open endpoint that doesn't require authentication
850
+ *
851
+ * @param senderAddress - Sender's Solana wallet address
852
+ * @param recipient - Username OR Solana address of the recipient
853
+ * @param amountMinor - Amount in USDC minor units or SOL lamports
854
+ * @param token - Token type ('USDC' or 'SOL'), defaults to 'USDC'
855
+ * @returns Prepared transaction info including base64 encoded transaction
856
+ */
857
+ prepareTransfer(senderAddress: string, recipient: string, amountMinor: number, token?: TransferToken): Promise<PrepareTransferResponse>;
858
+ /**
859
+ * Submit a signed transfer transaction
860
+ * This is an open endpoint that doesn't require authentication
861
+ *
862
+ * @param signedTransaction - Base64 encoded signed transaction
863
+ * @param senderAddress - Sender's Solana wallet address (for history tracking)
864
+ * @param recipientAddress - Recipient's Solana wallet address (for history tracking)
865
+ * @param amount - Transfer amount in minor units (for history tracking)
866
+ * @param token - Token type ('USDC' or 'SOL'), defaults to 'USDC'
867
+ * @returns Transaction signature and status
868
+ */
869
+ submitTransfer(signedTransaction: string, senderAddress: string, recipientAddress: string, amount: number, token?: TransferToken, ataCreated?: boolean, recipientInput?: string): Promise<SubmitTransferResponse>;
870
+ /**
871
+ * Full transfer flow in one call: prepare -> sign -> submit
872
+ * Recipient can be username, .sol domain, or Solana address (resolved by backend).
873
+ */
874
+ send(recipient: string, amount: number, token?: TransferToken): Promise<SendTransferResponse>;
875
+ }
876
+
877
+ declare class Auth {
878
+ private http;
879
+ private storage;
880
+ private wallet;
881
+ private logger;
882
+ constructor(http: IHttpClient, storage: IStorage, wallet: Wallet, logger?: ILogger);
883
+ login(email: string, password: string): Promise<LoginResponse>;
884
+ private generateHandshake;
885
+ loginWithWallet(options?: {
886
+ referralCode?: string;
887
+ walletMeta?: WalletMeta;
888
+ }): Promise<LoginResponse>;
889
+ logout(): void;
890
+ isAuthenticated(): boolean;
891
+ getLatestSessions(limit?: number): Promise<PaginatedSessions>;
892
+ }
893
+
894
+ declare class Admin {
895
+ private http;
896
+ private logger?;
897
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
898
+ getUserById(id: string): Promise<User>;
899
+ getStats(): Promise<AdminStats>;
900
+ getAdminStats(): Promise<AdminStats>;
901
+ getDailyStats(days?: number): Promise<AdminDailyStats>;
902
+ getAdminDailyStats(days?: number): Promise<AdminDailyStats>;
903
+ getEscrowSweepPreview(): Promise<EscrowSweepPreview>;
904
+ getEscrowSweeps(limit?: number): Promise<EscrowSweepRecord[]>;
905
+ executeEscrowSweep(amountUsdcMinor: number, idempotencyKey?: string): Promise<EscrowSweepRecord>;
906
+ banUser(userId: string, reason?: string): Promise<User>;
907
+ unbanUser(userId: string): Promise<User>;
908
+ getCriticalIncidentSummary(hours?: number): Promise<CriticalIncidentSummary>;
909
+ getCriticalIncidents(input: {
910
+ page?: number;
911
+ limit?: number;
912
+ status?: CriticalIncidentStatus;
913
+ severity?: CriticalIncidentSeverity;
914
+ category?: CriticalIncidentCategory;
915
+ }): Promise<PaginatedCriticalIncidents>;
916
+ resolveCriticalIncident(id: string, resolutionNote?: string): Promise<CriticalIncident>;
917
+ }
918
+
919
+ declare class Users {
920
+ private http;
921
+ private logger?;
922
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
923
+ getUsers(page?: number, limit?: number, username?: string, address?: string): Promise<PaginatedUsers>;
924
+ getUserById(id: string): Promise<User>;
925
+ isUsernameAvailable(username: string): Promise<UsernameAvailabilityResponse>;
926
+ updateUsername(username: string): Promise<User>;
927
+ getPublicUserByUsername(username: string): Promise<PublicUser>;
928
+ /**
929
+ * Get a public user profile by ID.
930
+ * Returns PublicUser with optional spectatorCount.
931
+ */
932
+ getPublicUserById(userId: string): Promise<PublicUser>;
933
+ searchUsers(username: string, page?: number, limit?: number): Promise<PaginatedSearchUsers>;
934
+ getFriends(userId: string, page?: number, limit?: number, search?: string): Promise<PaginatedFriends>;
935
+ addFriend(userId: string): Promise<{
936
+ message: string;
937
+ friendshipStatus: 'outgoing' | 'friends';
938
+ }>;
939
+ removeFriend(userId: string): Promise<{
940
+ message: string;
941
+ }>;
942
+ getIncomingFriendRequests(): Promise<FriendRequestItem[]>;
943
+ getOutgoingFriendRequests(): Promise<FriendRequestItem[]>;
944
+ acceptFriendRequest(userId: string): Promise<{
945
+ message: string;
946
+ }>;
947
+ declineFriendRequest(userId: string): Promise<{
948
+ message: string;
949
+ }>;
950
+ cancelFriendRequest(userId: string): Promise<{
951
+ message: string;
952
+ }>;
953
+ updateProfile(data: {
954
+ bio?: string;
955
+ username?: string;
956
+ }): Promise<User>;
957
+ uploadAvatar(file: File): Promise<User>;
958
+ uploadCoverImage(file: File): Promise<User>;
959
+ removeAvatar(): Promise<User>;
960
+ removeCoverImage(): Promise<User>;
961
+ getAllFiles(): Promise<Array<{
962
+ id: string;
963
+ path: string;
964
+ filename: string;
965
+ type: 'avatar' | 'cover';
966
+ userId: string;
967
+ size: number;
968
+ createdAt: string;
969
+ }>>;
970
+ deleteFile(fileId: string): Promise<{
971
+ message: string;
972
+ }>;
973
+ getGameHistory(userId: string): Promise<GameHistoryItem[]>;
974
+ /**
975
+ * Get user activity for spectate flow. Returns in_game (with gameId, gameType), in_lobby (with lobbyId, lobbyStatus), or idle.
976
+ */
977
+ getUserActivity(userId: string): Promise<UserActivity>;
978
+ /**
979
+ * Get the current active game for a user (if they are a player in one).
980
+ * Returns null if the user is not in an active game.
981
+ */
982
+ getCurrentGame(userId: string): Promise<CurrentGame | null>;
983
+ getUserStats(userId: string): Promise<UserStats>;
984
+ }
985
+
986
+ declare class FeatureFlags {
987
+ private http;
988
+ private logger?;
989
+ private flags;
990
+ private loaded;
991
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
992
+ getFeatureFlags(): Promise<FeatureFlag[]>;
993
+ isEnabledFlag(name: string): boolean;
994
+ isLoaded(): boolean;
995
+ updateFeatureFlag(name: string, enabled: boolean): Promise<FeatureFlag>;
996
+ createFeatureFlag(name: string, enabled: boolean): Promise<FeatureFlag>;
997
+ }
998
+
999
+ interface BetOption {
1000
+ amount: MoneyMinor;
1001
+ playersOnline: number;
1002
+ estimatedTime: string;
1003
+ }
1004
+ interface LobbyPlayer {
1005
+ userId: string;
1006
+ username?: string;
1007
+ avatar?: string;
1008
+ joinedAt: string;
1009
+ connected?: boolean;
1010
+ /** USDC balance in minor units (cached, short TTL). Shown in lobby and used to gate Start Game. */
1011
+ usdcBalance?: number;
1012
+ }
1013
+ interface Lobby {
1014
+ id: string;
1015
+ gameType: string;
1016
+ gameName: string;
1017
+ status: 'waiting' | 'preparing' | 'queued' | 'active';
1018
+ creatorId: string;
1019
+ maxPlayers: number;
1020
+ betAmount?: MoneyMinor;
1021
+ betOptions?: BetOption[];
1022
+ gameId?: string;
1023
+ createdAt: string;
1024
+ updatedAt: string;
1025
+ players: LobbyPlayer[];
1026
+ }
1027
+ interface CreateLobbyRequest {
1028
+ gameType: string;
1029
+ }
1030
+ interface InviteFriendRequest {
1031
+ friendId: string;
1032
+ }
1033
+ interface QueueStats {
1034
+ totalPlayersInQueue: number;
1035
+ queueSizes: Record<string, number>;
1036
+ totalQueuedLobbies: number;
1037
+ }
1038
+ type ChatMessageType = 'user' | 'system';
1039
+ type SystemMessageType = 'player_joined' | 'player_left' | 'bet_changed' | 'call_joined' | 'call_left' | 'global_help' | 'global_challenge' | 'global_tip' | 'spectator_donation';
1040
+ interface ChatMessageReply {
1041
+ id: string;
1042
+ userId?: string;
1043
+ username?: string;
1044
+ message: string;
1045
+ }
1046
+ interface ChatReaction {
1047
+ emoji: string;
1048
+ userId: string;
1049
+ username?: string;
1050
+ createdAt: string;
1051
+ }
1052
+ interface ChatReadBy {
1053
+ userId: string;
1054
+ readAt: string;
1055
+ }
1056
+ interface ChatMessage {
1057
+ id: string;
1058
+ lobbyId: string;
1059
+ userId?: string;
1060
+ username?: string;
1061
+ avatarUrl?: string;
1062
+ message: string;
1063
+ type: ChatMessageType;
1064
+ systemType?: SystemMessageType;
1065
+ metadata?: Record<string, any>;
1066
+ replyTo?: ChatMessageReply;
1067
+ reactions?: ChatReaction[];
1068
+ readBy?: ChatReadBy[];
1069
+ createdAt: string;
1070
+ }
1071
+
1072
+ declare class Lobbies {
1073
+ private http;
1074
+ private logger?;
1075
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
1076
+ createLobby(gameType: string, betAmount?: MoneyMinor): Promise<Lobby>;
1077
+ getLobby(lobbyId: string): Promise<Lobby>;
1078
+ inviteFriend(lobbyId: string, friendId: string): Promise<{
1079
+ message: string;
1080
+ }>;
1081
+ acceptInvite(lobbyId: string): Promise<Lobby>;
1082
+ joinLobby(lobbyId: string): Promise<Lobby>;
1083
+ removePlayer(lobbyId: string, userId: string): Promise<{
1084
+ message: string;
1085
+ }>;
1086
+ kickPlayer(lobbyId: string, userId: string): Promise<{
1087
+ message: string;
1088
+ }>;
1089
+ leaveLobby(lobbyId: string): Promise<{
1090
+ message: string;
1091
+ }>;
1092
+ joinQueue(lobbyId: string): Promise<Lobby>;
1093
+ cancelQueue(lobbyId: string): Promise<Lobby>;
1094
+ updateBetAmount(lobbyId: string, betAmount: MoneyMinor): Promise<Lobby>;
1095
+ playSound(lobbyId: string, sound: string): Promise<{
1096
+ success: boolean;
1097
+ }>;
1098
+ getActiveLobbies(): Promise<Lobby[]>;
1099
+ getQueueStats(): Promise<QueueStats>;
1100
+ deleteLobby(lobbyId: string): Promise<{
1101
+ message: string;
1102
+ }>;
1103
+ /**
1104
+ * Play again: Create a new lobby, start deposits, and prepare deposit transaction
1105
+ * Returns the lobby and unsigned transaction that needs to be signed
1106
+ * @param gameType - The game type to play again
1107
+ * @param betAmount - The bet amount (same as previous game)
1108
+ * @param escrow - The escrow service instance (from sdk.escrow)
1109
+ */
1110
+ playAgain(gameType: string, betAmount: MoneyMinor, escrow: {
1111
+ startDeposits: (id: string) => Promise<void>;
1112
+ prepareDepositTransaction: (id: string) => Promise<{
1113
+ transaction: string;
1114
+ message: string;
1115
+ }>;
1116
+ }): Promise<{
1117
+ lobby: Lobby;
1118
+ unsignedTransaction: string;
1119
+ }>;
1120
+ }
1121
+
1122
+ interface GameType {
1123
+ id: string;
1124
+ name: string;
1125
+ maxPlayers: number;
1126
+ minPlayers: number;
1127
+ description?: string;
1128
+ available: boolean;
1129
+ betOptions?: BetOption[];
1130
+ }
1131
+ /**
1132
+ * Real-time metrics for a game type.
1133
+ * Includes player counts, active games, and money currently in play.
1134
+ */
1135
+ interface GameMetrics {
1136
+ /** The game type identifier (e.g., 'chess', 'rock-paper-scissors') */
1137
+ gameType: string;
1138
+ /** Number of users currently playing or waiting in lobbies for this game type */
1139
+ usersPlaying: number;
1140
+ /** Number of active games currently in progress */
1141
+ liveGames: number;
1142
+ /** Total amount of money (in minor units) currently wagered in active games */
1143
+ moneyInPlay: number;
1144
+ }
1145
+ interface GamePlayer {
1146
+ userId: string;
1147
+ username: string;
1148
+ avatar?: string;
1149
+ status?: 'active' | 'disconnected';
1150
+ }
1151
+ interface Game {
1152
+ gameId: string;
1153
+ gameType: string;
1154
+ status: 'active' | 'completed' | 'abandoned';
1155
+ createdAt: string;
1156
+ players: GamePlayer[];
1157
+ lobbyIds: string[];
1158
+ }
1159
+ interface AdminGameHistoryPlayer {
1160
+ userId: string;
1161
+ username?: string;
1162
+ avatar?: string;
1163
+ }
1164
+ interface AdminGameHistoryFeePlayer {
1165
+ userId: string;
1166
+ username?: string;
1167
+ betAmount: MoneyMinor;
1168
+ feeAmount: MoneyMinor;
1169
+ netAmount: MoneyMinor;
1170
+ discountApplied: boolean;
1171
+ referralPayout: MoneyMinor;
1172
+ platformFeeNet: MoneyMinor;
1173
+ referralSplits: {
1174
+ level: number;
1175
+ referrerId: string;
1176
+ referrerUsername?: string;
1177
+ amount: MoneyMinor;
1178
+ }[];
1179
+ }
1180
+ interface AdminGameHistoryFeeBreakdown {
1181
+ totalDeposited: MoneyMinor;
1182
+ totalFee: MoneyMinor;
1183
+ totalPayout: MoneyMinor;
1184
+ players: AdminGameHistoryFeePlayer[];
1185
+ }
1186
+ interface SpectatorMetricsByUser {
1187
+ userId: string;
1188
+ spectatorCount: number;
1189
+ }
1190
+ interface SpectatorMetrics {
1191
+ total: number;
1192
+ byUser: SpectatorMetricsByUser[];
1193
+ }
1194
+ interface AdminGameHistory {
1195
+ id: string;
1196
+ gameId: string;
1197
+ gameType: string;
1198
+ playerIds: string[];
1199
+ players: AdminGameHistoryPlayer[];
1200
+ winnerId?: string;
1201
+ winner?: AdminGameHistoryPlayer;
1202
+ betAmount: MoneyMinor | null;
1203
+ wonAmount: MoneyMinor | null;
1204
+ totalDeposited: MoneyMinor | null;
1205
+ feeBreakdown?: AdminGameHistoryFeeBreakdown;
1206
+ depositTransactionHashes: string[];
1207
+ payoutTransactionHash?: string;
1208
+ feeTransactionHash?: string;
1209
+ completedAt: string;
1210
+ createdAt: string;
1211
+ }
1212
+ type GameStateResponse = RpsGameState | ChessGameState | NimGameState | DotsAndBoxesGameState | TicTacToeGameState | Connect4GameState;
1213
+ type ValidAction = RpsGameAction | ChessGameAction | NimGameAction | DotsAndBoxesGameAction | TicTacToeGameAction | Connect4GameAction;
1214
+
1215
+ interface DonateToGameResponse {
1216
+ signature: string;
1217
+ status: string;
1218
+ escrowAddress: string;
1219
+ amountMinor: number;
1220
+ }
1221
+ declare class Games {
1222
+ private http;
1223
+ private wallet;
1224
+ private logger?;
1225
+ constructor(http: IHttpClient, wallet: Wallet, logger?: ILogger | undefined);
1226
+ getAvailableGames(): Promise<GameType[]>;
1227
+ /**
1228
+ * Get real-time metrics for all games.
1229
+ * Returns player counts, active games, and money in play per game type.
1230
+ * This is a public endpoint that doesn't require authentication.
1231
+ */
1232
+ getMetrics(): Promise<GameMetrics[]>;
1233
+ getGame(gameId: string): Promise<Game>;
1234
+ /**
1235
+ * Get list of currently active (live) games. Public endpoint for spectating.
1236
+ */
1237
+ getLiveGames(): Promise<Game[]>;
1238
+ getAdminGameHistory(gameId: string): Promise<AdminGameHistory>;
1239
+ /**
1240
+ * Get current spectator counts (total and per user). Admin only.
1241
+ */
1242
+ getSpectatorMetrics(): Promise<SpectatorMetrics>;
1243
+ /**
1244
+ * Submit a typed action for any game
1245
+ */
1246
+ submitAction(gameId: string, action: ValidAction): Promise<void>;
1247
+ /**
1248
+ * Get current game state with timer information
1249
+ */
1250
+ getGameState(gameId: string): Promise<GameStateResponse>;
1251
+ /**
1252
+ * Request a rematch for a completed game
1253
+ */
1254
+ requestRematch(gameId: string): Promise<{
1255
+ success: boolean;
1256
+ bothReady: boolean;
1257
+ newGameId?: string;
1258
+ }>;
1259
+ /**
1260
+ * Cancel a rematch request
1261
+ */
1262
+ cancelRematch(gameId: string): Promise<{
1263
+ success: boolean;
1264
+ }>;
1265
+ /**
1266
+ * Get current rematch state for a game
1267
+ */
1268
+ getRematchState(gameId: string): Promise<{
1269
+ requestedBy: string[];
1270
+ }>;
1271
+ /**
1272
+ * Prepare a game donation (returns unsigned transaction for client to sign).
1273
+ * Call donateToGame with the signed transaction after signing.
1274
+ */
1275
+ prepareGameDonation(gameId: string, amountMinor: number): Promise<{
1276
+ transaction: string;
1277
+ escrowAddress: string;
1278
+ amountMinor: number;
1279
+ }>;
1280
+ /**
1281
+ * Submit a signed game donation. Sign the transaction from prepareGameDonation first.
1282
+ */
1283
+ donateToGame(gameId: string, amountMinor: number, signedTransaction: string): Promise<{
1284
+ signature: string;
1285
+ status: string;
1286
+ }>;
1287
+ /**
1288
+ * One-call donation flow: prepare -> sign -> submit.
1289
+ */
1290
+ sendDonation(gameId: string, amountMinor: number): Promise<DonateToGameResponse>;
1291
+ /**
1292
+ * Notify backend that a rematch lobby was created (coordinator calls this)
1293
+ * Backend will broadcast the lobby ID to other players
1294
+ */
1295
+ notifyRematchLobbyCreated(gameId: string, lobbyId: string): Promise<void>;
1296
+ }
1297
+
1298
+ /** A player currently in an active game; used for "Live now" and "Who to watch" UI. */
1299
+ interface LivePlayer {
1300
+ userId: string;
1301
+ username: string;
1302
+ avatar?: string;
1303
+ gameId: string;
1304
+ gameType: string;
1305
+ spectatorCount: number;
1306
+ }
1307
+ /** Paginated response for live players (newest first, sample of games per page). */
1308
+ interface LivePlayersPage {
1309
+ items: LivePlayer[];
1310
+ nextCursor: string | null;
1311
+ }
1312
+ /**
1313
+ * SDK class for spectate discovery — finding who to watch.
1314
+ *
1315
+ * @example
1316
+ * ```ts
1317
+ * const page = await sdk.spectate.getLivePlayers({ limit: 10 });
1318
+ * console.log(page.items); // LivePlayer[]
1319
+ * ```
1320
+ */
1321
+ declare class Spectate {
1322
+ private http;
1323
+ private logger?;
1324
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
1325
+ /**
1326
+ * Get list of live players (one per unique player), sampled from newest games, paginated.
1327
+ * Use for "Live now" and "Who to watch" UI; link to /spectate/:username.
1328
+ * @param options.limit - Number of games to consider per page (1–20, default 10).
1329
+ * @param options.cursor - Opaque cursor from previous page for next page.
1330
+ */
1331
+ getLivePlayers(options?: {
1332
+ limit?: number;
1333
+ cursor?: string;
1334
+ }): Promise<LivePlayersPage>;
1335
+ }
1336
+
1337
+ /**
1338
+ * Retry configuration options
1339
+ */
1340
+ interface RetryOptions {
1341
+ /** Maximum number of retry attempts (default: 3) */
1342
+ maxAttempts?: number;
1343
+ /** Base delay in milliseconds (default: 1000) */
1344
+ baseDelayMs?: number;
1345
+ /** Maximum delay in milliseconds (default: 10000) */
1346
+ maxDelayMs?: number;
1347
+ /** Multiplier for exponential backoff (default: 2) */
1348
+ backoffMultiplier?: number;
1349
+ /** Function to determine if error is retryable (default: network/5xx errors) */
1350
+ isRetryable?: (error: unknown) => boolean;
1351
+ /** Callback for each retry attempt */
1352
+ onRetry?: (attempt: number, error: unknown, delayMs: number) => void;
1353
+ }
1354
+ /**
1355
+ * Default function to determine if an error is retryable.
1356
+ * Retries on network errors and 5xx server errors.
1357
+ */
1358
+ declare function isRetryableError(error: unknown): boolean;
1359
+ /**
1360
+ * Execute an async function with exponential backoff retry.
1361
+ *
1362
+ * @param fn - Async function to execute
1363
+ * @param options - Retry configuration
1364
+ * @returns Promise resolving to the function result
1365
+ * @throws Last error if all retries exhausted
1366
+ *
1367
+ * @example
1368
+ * ```typescript
1369
+ * const result = await withRetry(
1370
+ * () => fetch('/api/data'),
1371
+ * { maxAttempts: 3, baseDelayMs: 500 }
1372
+ * );
1373
+ * ```
1374
+ */
1375
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1376
+
1377
+ type ChatContextType = 'lobby' | 'game' | 'dm' | 'global';
1378
+ interface ChatContext {
1379
+ type: ChatContextType;
1380
+ id: string;
1381
+ }
1382
+ interface SendMessageRequest {
1383
+ message: string;
1384
+ replyTo?: ChatMessageReply;
1385
+ gifUrl?: string;
1386
+ }
1387
+ interface DmThread {
1388
+ dmKey: string;
1389
+ otherUser: PublicUser;
1390
+ lastMessage: string | null;
1391
+ lastMessageAt: string | null;
1392
+ lastMessageSenderId: string | null;
1393
+ lastMessageSenderUsername: string | null;
1394
+ unreadCount: number;
1395
+ }
1396
+ declare class Chat {
1397
+ private http;
1398
+ private logger?;
1399
+ private retryOptions;
1400
+ constructor(http: IHttpClient, logger?: any | undefined, retryOptions?: RetryOptions);
1401
+ private encodeContextId;
1402
+ /**
1403
+ * Send a chat message with automatic retry on transient failures
1404
+ *
1405
+ * @param clientMessageId - Optional client-generated ID for optimistic UI.
1406
+ * Echoed back in response metadata for deduplication.
1407
+ */
1408
+ sendMessage(context: ChatContext, message: string, replyTo?: ChatMessageReply, gifUrl?: string, clientMessageId?: string): Promise<ChatMessage>;
1409
+ /** Response from paginated chat history */
1410
+ getChatHistory(context: ChatContext, limit?: number, cursor?: string): Promise<ChatMessage[]>;
1411
+ /**
1412
+ * Get chat history with pagination support.
1413
+ * Returns messages and a cursor for loading older messages.
1414
+ * For global context, uses the public endpoint so it works without auth.
1415
+ */
1416
+ getChatHistoryPaginated(context: ChatContext, limit?: number, cursor?: string): Promise<{
1417
+ messages: ChatMessage[];
1418
+ nextCursor: string | null;
1419
+ }>;
1420
+ /**
1421
+ * Add a reaction to a message
1422
+ */
1423
+ addReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1424
+ /**
1425
+ * Remove a reaction from a message
1426
+ */
1427
+ removeReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1428
+ /**
1429
+ * Mark a message as read
1430
+ */
1431
+ markAsRead(context: ChatContext, messageId: string): Promise<ChatMessage>;
1432
+ listDmThreads(): Promise<DmThread[]>;
1433
+ getDmThread(dmKey: string): Promise<DmThread>;
1434
+ /**
1435
+ * Mark all messages in a DM thread as read
1436
+ */
1437
+ markDmThreadAsRead(dmKey: string): Promise<{
1438
+ markedCount: number;
1439
+ }>;
1440
+ /**
1441
+ * Accept a global chat challenge. Returns the lobby (and gameId if started).
1442
+ */
1443
+ acceptGlobalChallenge(challengeId: string): Promise<{
1444
+ lobbyId: string;
1445
+ gameId?: string;
1446
+ status: string;
1447
+ }>;
1448
+ /**
1449
+ * Broadcast a tip message to global chat (call after the user has signed and submitted the transfer).
1450
+ */
1451
+ broadcastGlobalTip(recipientUserId: string, amount: number): Promise<ChatMessage>;
1452
+ }
1453
+
1454
+ interface CreateChallengeRequest {
1455
+ gameType: string;
1456
+ amount: number;
1457
+ targetUserId?: string;
1458
+ targetUsername?: string;
1459
+ /** When set, post challenge system message to this DM thread (format: "userId1:userId2" sorted). */
1460
+ dmKey?: string;
1461
+ }
1462
+ interface CreateChallengeResponse {
1463
+ challengeId: string;
1464
+ challengerId: string;
1465
+ targetUserId: string;
1466
+ gameType: string;
1467
+ amountMinor: number;
1468
+ challengerUsername?: string;
1469
+ }
1470
+ interface AcceptChallengeResponse {
1471
+ lobbyId: string;
1472
+ gameId?: string;
1473
+ status: string;
1474
+ }
1475
+ declare class Challenges {
1476
+ private http;
1477
+ private logger?;
1478
+ constructor(http: IHttpClient, logger?: any | undefined);
1479
+ /**
1480
+ * Create a challenge (any user can challenge any other user by id or username).
1481
+ */
1482
+ create(dto: CreateChallengeRequest): Promise<CreateChallengeResponse>;
1483
+ /**
1484
+ * Accept a challenge. Only the challenged user can accept. Creates a lobby with the challenge amount and adds both users.
1485
+ */
1486
+ accept(challengeId: string): Promise<AcceptChallengeResponse>;
1487
+ /**
1488
+ * Decline a challenge. Only the challenged user can decline. Optionally post a "declined" message to the DM thread.
1489
+ */
1490
+ decline(challengeId: string, dmKey?: string): Promise<{
1491
+ message?: string;
1492
+ }>;
1493
+ }
1494
+
1495
+ interface PrepareTipRequest {
1496
+ recipientUsername: string;
1497
+ amount: number;
1498
+ }
1499
+ interface PrepareTipResponse {
1500
+ transaction: string;
1501
+ fee: number;
1502
+ totalAmount: number;
1503
+ recipientAddress: string;
1504
+ recipientUserId: string;
1505
+ recipientUsername: string;
1506
+ amount: number;
1507
+ }
1508
+ interface BroadcastTipRequest {
1509
+ recipientUserId: string;
1510
+ amount: number;
1511
+ }
1512
+ interface SendTipResponse extends SubmitTransferResponse {
1513
+ recipientAddress: string;
1514
+ recipientUserId: string;
1515
+ recipientUsername: string;
1516
+ amount: number;
1517
+ fee: number;
1518
+ totalAmount: number;
1519
+ message: ChatMessage;
1520
+ }
1521
+ /**
1522
+ * Tips are a shorthand for wallet send + global tip broadcast.
1523
+ */
1524
+ declare class Tips {
1525
+ private http;
1526
+ private wallet;
1527
+ private chat;
1528
+ private logger?;
1529
+ constructor(http: IHttpClient, wallet: Wallet, chat: Chat, logger?: any | undefined);
1530
+ prepare(dto: PrepareTipRequest): Promise<PrepareTipResponse>;
1531
+ /**
1532
+ * Broadcast a tip message to global chat (call after the transfer has been submitted).
1533
+ */
1534
+ broadcast(dto: BroadcastTipRequest): Promise<ChatMessage>;
1535
+ /**
1536
+ * One-call tip flow: prepare -> sign -> submit transfer -> broadcast tip message.
1537
+ */
1538
+ send(recipientUsername: string, amount: number): Promise<SendTipResponse>;
1539
+ }
1540
+
1541
+ type WsEventName = 'lobby:created' | 'lobby:updated' | 'lobby:player:joined' | 'lobby:player:left' | 'lobby:player:connected' | 'lobby:player:disconnected' | 'lobby:bet:updated' | 'lobby:invitation' | 'lobby:deleted' | 'lobby:queue:joined' | 'lobby:queue:cancelled' | 'lobby:matched' | 'lobby:typing:start' | 'lobby:typing:stop' | 'game:updated' | 'game:completed' | 'game:paid' | 'game:abandoned' | 'game:turn' | 'game:move' | 'game:state' | 'game:player:connected' | 'game:player:disconnected' | 'game:rps:starting' | 'game:rps:round:started' | 'game:rps:action:received' | 'game:rps:timer:cutoff' | 'game:rps:round:reveal' | 'game:rps:round:completed' | 'game:rps:timeout' | 'game:rematch:requested' | 'game:rematch:cancelled' | 'game:rematch:started' | 'game:rematch:lobby:created' | 'game:pot:updated' | 'game:market:price:updated' | 'game:market:order:filled' | 'game:market:resolved' | 'spectator:count:updated' | 'chat:message' | 'chat:reaction' | 'chat:read' | 'chat:typing' | 'notification';
1542
+ type GameTurnPayload = {
1543
+ turn: number;
1544
+ currentPlayerId: string;
1545
+ gameId?: string;
1546
+ [key: string]: unknown;
1547
+ };
1548
+ type GameMovePayload = ChessMovePayload;
1549
+ type GameStatePayload = {
1550
+ state: GameStateResponse;
1551
+ gameId?: string;
1552
+ };
1553
+ type GamePlayerConnectionPayload = {
1554
+ userId: string;
1555
+ gameId: string;
1556
+ };
1557
+ type GameStartingPayload = {
1558
+ gameId: string;
1559
+ startedAt: string;
1560
+ bufferEndsAt: string;
1561
+ timeRemaining: number;
1562
+ betAmount: MoneyMinor;
1563
+ };
1564
+ type GameRoundStartedPayload = {
1565
+ gameId: string;
1566
+ roundNumber: number;
1567
+ startedAt: string;
1568
+ selectionEndsAt: string;
1569
+ timeRemaining: number;
1570
+ };
1571
+ type GameActionReceivedPayload = {
1572
+ gameId: string;
1573
+ roundNumber: number;
1574
+ playerId: string;
1575
+ submittedAt: string;
1576
+ };
1577
+ type GameTimerCutoffPayload = {
1578
+ gameId: string;
1579
+ roundNumber: number;
1580
+ cutoffAt: string;
1581
+ newEndsAt: string;
1582
+ };
1583
+ type GameRoundRevealPayload = {
1584
+ gameId: string;
1585
+ roundNumber: number;
1586
+ actions: Record<string, RpsAction>;
1587
+ revealEndsAt: string;
1588
+ timeRemaining: number;
1589
+ };
1590
+ type GameRoundCompletedPayload = {
1591
+ gameId: string;
1592
+ roundNumber: number;
1593
+ winnerId: string | null;
1594
+ scores: Record<string, number>;
1595
+ actions: Record<string, RpsAction>;
1596
+ };
1597
+ type GameTimeoutPayload = {
1598
+ gameId: string;
1599
+ roundNumber: number;
1600
+ playerId: string;
1601
+ action: RpsAction;
1602
+ isTimeout: boolean;
1603
+ };
1604
+ type GameCompletionBasePayload = {
1605
+ gameId: string;
1606
+ gameType: GameStateResponse['gameType'];
1607
+ winnerId: string | null;
1608
+ wonAmount: number;
1609
+ isDraw: boolean;
1610
+ };
1611
+ type RpsGameCompletionPayload = GameCompletionBasePayload & {
1612
+ gameType: 'rock-paper-scissors';
1613
+ finalScores: Record<string, number>;
1614
+ rounds: Array<{
1615
+ roundNumber: number;
1616
+ actions: Record<string, RpsAction>;
1617
+ winnerId: string | null;
1618
+ completedAt?: string;
1619
+ }>;
1620
+ };
1621
+ type GenericGameCompletionPayload = GameCompletionBasePayload & {
1622
+ gameType: Exclude<GameStateResponse['gameType'], 'rock-paper-scissors'>;
1623
+ };
1624
+ type GameCompletionPayload = RpsGameCompletionPayload | GenericGameCompletionPayload;
1625
+ type MarketPriceUpdatedPayload = {
1626
+ gameId: string;
1627
+ prices: Record<string, number>;
1628
+ totalCollateral: string;
1629
+ totalVolume: string;
1630
+ };
1631
+ type MarketOrderFilledPayload = {
1632
+ gameId: string;
1633
+ orderId: string;
1634
+ userId: string;
1635
+ outcomeId: string;
1636
+ filledQuantity: string;
1637
+ pricePerShare: string;
1638
+ };
1639
+ type MarketResolvedPayload = {
1640
+ gameId: string;
1641
+ resolvedOutcome: string | null;
1642
+ isDraw: boolean;
1643
+ };
1644
+ type WsEvent = {
1645
+ event: 'lobby:created';
1646
+ payload: Lobby;
1647
+ } | {
1648
+ event: 'lobby:updated';
1649
+ payload: Lobby;
1650
+ } | {
1651
+ event: 'lobby:player:joined';
1652
+ payload: {
1653
+ userId: string;
1654
+ lobby: Lobby;
1655
+ };
1656
+ } | {
1657
+ event: 'lobby:player:left';
1658
+ payload: {
1659
+ userId: string;
1660
+ lobby: Lobby;
1661
+ };
1662
+ } | {
1663
+ event: 'lobby:player:connected';
1664
+ payload: {
1665
+ userId: string;
1666
+ lobbyId: string;
1667
+ };
1668
+ } | {
1669
+ event: 'lobby:player:disconnected';
1670
+ payload: {
1671
+ userId: string;
1672
+ lobbyId: string;
1673
+ };
1674
+ } | {
1675
+ event: 'lobby:bet:updated';
1676
+ payload: Lobby;
1677
+ } | {
1678
+ event: 'lobby:invitation';
1679
+ payload: unknown;
1680
+ } | {
1681
+ event: 'lobby:deleted';
1682
+ payload: {
1683
+ lobbyId: string;
1684
+ };
1685
+ } | {
1686
+ event: 'lobby:queue:joined';
1687
+ payload: {
1688
+ lobby: Lobby;
1689
+ queuedAt: string;
1690
+ };
1691
+ } | {
1692
+ event: 'lobby:queue:cancelled';
1693
+ payload: {
1694
+ lobby: Lobby;
1695
+ };
1696
+ } | {
1697
+ event: 'lobby:matched';
1698
+ payload: {
1699
+ gameId: string;
1700
+ gameType: string;
1701
+ matchedLobbies: Lobby[];
1702
+ };
1703
+ } | {
1704
+ event: 'lobby:typing:start';
1705
+ payload: {
1706
+ lobbyId: string;
1707
+ userId: string;
1708
+ };
1709
+ } | {
1710
+ event: 'lobby:typing:stop';
1711
+ payload: {
1712
+ lobbyId: string;
1713
+ userId: string;
1714
+ };
1715
+ } | {
1716
+ event: 'game:updated';
1717
+ payload: Game;
1718
+ } | {
1719
+ event: 'game:completed';
1720
+ payload: GameCompletionPayload;
1721
+ } | {
1722
+ event: 'game:paid';
1723
+ payload: GameCompletionPayload;
1724
+ } | {
1725
+ event: 'game:abandoned';
1726
+ payload: Game;
1727
+ } | {
1728
+ event: 'game:turn';
1729
+ payload: GameTurnPayload;
1730
+ } | {
1731
+ event: 'game:move';
1732
+ payload: GameMovePayload;
1733
+ } | {
1734
+ event: 'game:state';
1735
+ payload: GameStatePayload;
1736
+ } | {
1737
+ event: 'game:player:connected';
1738
+ payload: GamePlayerConnectionPayload;
1739
+ } | {
1740
+ event: 'game:player:disconnected';
1741
+ payload: GamePlayerConnectionPayload;
1742
+ } | {
1743
+ event: 'game:rps:starting';
1744
+ payload: GameStartingPayload;
1745
+ } | {
1746
+ event: 'game:rps:round:started';
1747
+ payload: GameRoundStartedPayload;
1748
+ } | {
1749
+ event: 'game:rps:action:received';
1750
+ payload: GameActionReceivedPayload;
1751
+ } | {
1752
+ event: 'game:rps:timer:cutoff';
1753
+ payload: GameTimerCutoffPayload;
1754
+ } | {
1755
+ event: 'game:rps:round:reveal';
1756
+ payload: GameRoundRevealPayload;
1757
+ } | {
1758
+ event: 'game:rps:round:completed';
1759
+ payload: GameRoundCompletedPayload;
1760
+ } | {
1761
+ event: 'game:rps:timeout';
1762
+ payload: GameTimeoutPayload;
1763
+ } | {
1764
+ event: 'game:rematch:requested';
1765
+ payload: {
1766
+ gameId: string;
1767
+ userId?: string;
1768
+ requestedBy?: string[];
1769
+ };
1770
+ } | {
1771
+ event: 'game:rematch:cancelled';
1772
+ payload: {
1773
+ gameId: string;
1774
+ userId?: string;
1775
+ requestedBy?: string[];
1776
+ };
1777
+ } | {
1778
+ event: 'game:rematch:started';
1779
+ payload: {
1780
+ gameId: string;
1781
+ gameType?: string;
1782
+ betAmount?: MoneyMinor;
1783
+ playerIds?: string[];
1784
+ coordinatorId?: string;
1785
+ newLobbyId?: string;
1786
+ };
1787
+ } | {
1788
+ event: 'game:rematch:lobby:created';
1789
+ payload: {
1790
+ gameId: string;
1791
+ newLobbyId: string;
1792
+ };
1793
+ } | {
1794
+ event: 'game:pot:updated';
1795
+ payload: {
1796
+ gameId: string;
1797
+ totalPotMinor: number;
1798
+ };
1799
+ } | {
1800
+ event: 'game:market:price:updated';
1801
+ payload: MarketPriceUpdatedPayload;
1802
+ } | {
1803
+ event: 'game:market:order:filled';
1804
+ payload: MarketOrderFilledPayload;
1805
+ } | {
1806
+ event: 'game:market:resolved';
1807
+ payload: MarketResolvedPayload;
1808
+ } | {
1809
+ event: 'spectator:count:updated';
1810
+ payload: {
1811
+ userId: string;
1812
+ count: number;
1813
+ };
1814
+ } | {
1815
+ event: 'chat:message';
1816
+ payload: ChatMessage;
1817
+ } | {
1818
+ event: 'chat:reaction';
1819
+ payload: ChatMessage;
1820
+ } | {
1821
+ event: 'chat:read';
1822
+ payload: {
1823
+ messageId: string;
1824
+ userId: string;
1825
+ readAt?: string;
1826
+ };
1827
+ } | {
1828
+ event: 'chat:typing';
1829
+ payload: {
1830
+ context: ChatContext;
1831
+ userId: string;
1832
+ username?: string;
1833
+ typing: boolean;
1834
+ };
1835
+ } | {
1836
+ event: 'notification';
1837
+ payload: unknown;
1838
+ };
1839
+
1840
+ type EqualityFn<T> = (a: T, b: T) => boolean;
1841
+ interface SdkStore<S> {
1842
+ getSnapshot(): S;
1843
+ getState(): S;
1844
+ setState(next: S): void;
1845
+ updateState(updater: (prev: S) => S): void;
1846
+ subscribe(listener: () => void): () => void;
1847
+ subscribeSelector<T>(selector: (state: S) => T, listener: () => void, isEqual?: EqualityFn<T>): () => void;
1848
+ }
1849
+ declare function createSdkStore<S>(initial: S): SdkStore<S>;
1850
+
1851
+ type NotificationEvent = {
1852
+ title: string;
1853
+ body?: string;
1854
+ icon?: string;
1855
+ tag?: string;
1856
+ data?: unknown;
1857
+ /** Notification type (e.g. challenge_accepted) for app logic like auto-navigation */
1858
+ type?: string;
1859
+ /** Action payload (e.g. { lobbyId }) when present on the payload */
1860
+ actionPayload?: Record<string, unknown>;
1861
+ };
1862
+
1863
+ type NotificationsStoreState = {
1864
+ notifications: NotificationEvent[];
1865
+ lastNotification: NotificationEvent | null;
1866
+ appNotifications: AppNotification[];
1867
+ };
1868
+ type NotificationsStore = {
1869
+ store: SdkStore<NotificationsStoreState>;
1870
+ applyWsEvent: (event: WsEvent) => void;
1871
+ setListFromApi: (res: PaginatedNotificationsResponse) => void;
1872
+ clear: () => void;
1873
+ };
1874
+ declare function createNotificationsStore(): NotificationsStore;
1875
+
1876
+ interface ListNotificationsParams {
1877
+ page?: number;
1878
+ limit?: number;
1879
+ }
1880
+ declare class Notifications {
1881
+ private http;
1882
+ private notificationsStore;
1883
+ private logger?;
1884
+ constructor(http: IHttpClient, notificationsStore: NotificationsStore, logger?: ILogger | undefined);
1885
+ /**
1886
+ * List notifications for the current user (paginated).
1887
+ * Results are always merged into the SDK notifications store.
1888
+ */
1889
+ list(params?: ListNotificationsParams): Promise<PaginatedNotificationsResponse>;
1890
+ /**
1891
+ * Mark a notification as read.
1892
+ */
1893
+ markAsRead(id: string): Promise<AppNotification>;
1894
+ /**
1895
+ * Mark all notifications as read.
1896
+ */
1897
+ markAllAsRead(): Promise<void>;
1898
+ /**
1899
+ * Dismiss (delete) a notification.
1900
+ */
1901
+ dismiss(id: string): Promise<void>;
1902
+ /**
1903
+ * Broadcast a notification to all connected users (admin only)
1904
+ */
1905
+ broadcastNotification(message: string): Promise<void>;
1906
+ /**
1907
+ * Send a notification to a specific user (admin only)
1908
+ */
1909
+ sendToUser(userId: string, message: string): Promise<void>;
1910
+ }
1911
+
1912
+ declare class Achievements {
1913
+ private http;
1914
+ private logger?;
1915
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
1916
+ /**
1917
+ * List all achievement definitions.
1918
+ */
1919
+ list(): Promise<Achievement[]>;
1920
+ /**
1921
+ * Get unlocked achievements for the current user.
1922
+ */
1923
+ getMyAchievements(): Promise<UserAchievement[]>;
1924
+ /**
1925
+ * Get unlocked achievements for a user (e.g. for profile).
1926
+ */
1927
+ getForUser(userId: string): Promise<UserAchievement[]>;
1928
+ }
1929
+
1930
+ interface DepositStatus {
1931
+ status: 'pending' | 'signed' | 'confirmed' | 'failed';
1932
+ transactionHash?: string;
1933
+ signedAt?: string;
1934
+ confirmedAt?: string;
1935
+ errorMessage?: string;
1936
+ }
1937
+ interface DepositStatusResponse {
1938
+ deposits: Array<{
1939
+ userId: string;
1940
+ status: 'pending' | 'signed' | 'confirmed' | 'failed';
1941
+ transactionHash?: string;
1942
+ signedAt?: string;
1943
+ confirmedAt?: string;
1944
+ errorMessage?: string;
1945
+ }>;
1946
+ allConfirmed: boolean;
1947
+ canProceedToQueue: boolean;
1948
+ }
1949
+ interface PrepareDepositResponse {
1950
+ transaction: string;
1951
+ message: string;
1952
+ }
1953
+ interface SubmitDepositResponse {
1954
+ signature: string;
1955
+ status: string;
1956
+ }
1957
+ declare class Escrow {
1958
+ private http;
1959
+ private logger?;
1960
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
1961
+ /**
1962
+ * Start the deposit flow for a lobby
1963
+ * Transitions the lobby to 'preparing' state
1964
+ */
1965
+ startDeposits(lobbyId: string): Promise<void>;
1966
+ /**
1967
+ * Prepare a deposit transaction for a user
1968
+ * Returns an unsigned transaction that needs to be signed by the user
1969
+ */
1970
+ prepareDepositTransaction(lobbyId: string): Promise<PrepareDepositResponse>;
1971
+ /**
1972
+ * Submit a signed deposit transaction
1973
+ * The transaction will be submitted to the Solana network and confirmed
1974
+ */
1975
+ submitDeposit(lobbyId: string, signedTransaction: string): Promise<SubmitDepositResponse>;
1976
+ /**
1977
+ * Check the deposit status for all players in a lobby
1978
+ */
1979
+ getDepositStatus(lobbyId: string): Promise<DepositStatusResponse>;
1980
+ claimLobbyDepositRefund(lobbyId: string, depositSignature: string): Promise<{
1981
+ signature: string;
1982
+ status: string;
1983
+ }>;
1984
+ claimGamePayout(gameHistoryId: string): Promise<{
1985
+ signature: string;
1986
+ status: string;
1987
+ }>;
1988
+ /**
1989
+ * Submit a signed deposit transaction and wait until the lobby is queued/active.
1990
+ *
1991
+ * Note: the backend may auto-transition the lobby to the queue once deposits are confirmed.
1992
+ * In that case, calling /join-queue from the client would be redundant and can fail with
1993
+ * "Current status: queued".
1994
+ * @param lobbyId - The lobby ID
1995
+ * @param signedTransaction - The signed transaction (base64 encoded)
1996
+ * @param lobbies - The lobbies service instance (from sdk.lobbies) to read lobby status
1997
+ */
1998
+ submitDepositAndJoinQueue(lobbyId: string, signedTransaction: string, lobbies: {
1999
+ getLobby: (id: string) => Promise<{
2000
+ id: string;
2001
+ status: string;
2002
+ }>;
2003
+ }): Promise<{
2004
+ id: string;
2005
+ status: string;
2006
+ }>;
2007
+ }
2008
+
2009
+ interface DailyRoom {
2010
+ roomUrl: string;
2011
+ roomName: string;
2012
+ lobbyId: string;
2013
+ createdAt: string;
2014
+ }
2015
+ interface DailyToken {
2016
+ token: string;
2017
+ roomUrl: string;
2018
+ expiresAt: string;
2019
+ }
2020
+ interface DailyParticipant {
2021
+ sessionId: string;
2022
+ userId: string;
2023
+ username?: string;
2024
+ avatarUrl?: string;
2025
+ audio: boolean;
2026
+ video: boolean;
2027
+ }
2028
+ declare class Daily {
2029
+ private http;
2030
+ private logger;
2031
+ constructor(http: IHttpClient, logger?: ILogger);
2032
+ createDmRoom(dmKey: string): Promise<DailyRoom>;
2033
+ getDmRoom(dmKey: string): Promise<DailyRoom | null>;
2034
+ getDmToken(dmKey: string): Promise<DailyToken>;
2035
+ deleteDmRoom(dmKey: string): Promise<void>;
2036
+ notifyDmCallJoined(dmKey: string): Promise<void>;
2037
+ notifyDmCallLeft(dmKey: string): Promise<void>;
2038
+ }
2039
+
2040
+ declare class Referrals {
2041
+ private http;
2042
+ private logger;
2043
+ constructor(http: IHttpClient, logger?: ILogger);
2044
+ getSummary(): Promise<ReferralSummary>;
2045
+ getTree(params?: {
2046
+ level?: 1 | 2 | 3;
2047
+ limit?: number;
2048
+ cursor?: string;
2049
+ }): Promise<ReferralTreeResponse>;
2050
+ getRewards(params?: {
2051
+ limit?: number;
2052
+ cursor?: string;
2053
+ status?: 'PENDING' | 'CLAIMED' | 'CANCELLED';
2054
+ }): Promise<ReferralRewardsResponse>;
2055
+ applyCode(referralCode: string): Promise<ApplyReferralCodeResponse>;
2056
+ claimRewards(): Promise<ClaimReferralRewardsResponse>;
2057
+ }
2058
+
2059
+ declare class Activity {
2060
+ private http;
2061
+ private logger?;
2062
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2063
+ getFeed(limit?: number): Promise<ActivityFeedResponse>;
2064
+ }
2065
+
2066
+ declare class Leaderboards {
2067
+ private http;
2068
+ private logger?;
2069
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2070
+ getGlobalLeaderboard(query?: LeaderboardQuery): Promise<LeaderboardResponse>;
2071
+ getGameLeaderboard(gameType: string, query?: LeaderboardQuery): Promise<LeaderboardResponse>;
2072
+ getFriendsLeaderboard(query?: LeaderboardQuery): Promise<LeaderboardResponse>;
2073
+ private buildEndpoint;
2074
+ }
2075
+
2076
+ interface GetReportsOptions {
2077
+ page?: number;
2078
+ limit?: number;
2079
+ status?: ReportStatus;
2080
+ }
2081
+ interface UpdateReportData {
2082
+ status?: ReportStatus;
2083
+ adminNotes?: string;
2084
+ }
2085
+ declare class Reports {
2086
+ private http;
2087
+ private logger?;
2088
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2089
+ /**
2090
+ * Create a new report (authenticated users only)
2091
+ * Rate limited to 5 reports per hour
2092
+ * @param reportedUserId - The ID of the user being reported
2093
+ * @param reason - The reason for the report (max 300 characters)
2094
+ */
2095
+ create(reportedUserId: string, reason: string): Promise<Report>;
2096
+ /**
2097
+ * Get all reports (admin only, paginated)
2098
+ * @param options - Pagination and filter options
2099
+ */
2100
+ list(options?: GetReportsOptions): Promise<PaginatedReports>;
2101
+ /**
2102
+ * Get a single report by ID (admin only)
2103
+ * @param id - The report ID
2104
+ */
2105
+ getById(id: string): Promise<Report>;
2106
+ /**
2107
+ * Get reports for a specific user (admin only)
2108
+ * @param userId - The ID of the reported user
2109
+ */
2110
+ getByUser(userId: string): Promise<Report[]>;
2111
+ /**
2112
+ * Get report count for a specific user (admin only)
2113
+ * @param userId - The ID of the reported user
2114
+ */
2115
+ getCountByUser(userId: string): Promise<ReportCount>;
2116
+ /**
2117
+ * Get count of pending reports (admin only)
2118
+ */
2119
+ getPendingCount(): Promise<{
2120
+ count: number;
2121
+ }>;
2122
+ /**
2123
+ * Update a report status/notes (admin only)
2124
+ * @param id - The report ID
2125
+ * @param data - Update data (status and/or adminNotes)
2126
+ */
2127
+ update(id: string, data: UpdateReportData): Promise<Report>;
2128
+ /**
2129
+ * Delete a report (admin only)
2130
+ * @param id - The report ID
2131
+ */
2132
+ delete(id: string): Promise<void>;
2133
+ }
2134
+
2135
+ interface CreateTicketData {
2136
+ /** Optional subject (auto-generated from category if omitted) */
2137
+ subject?: string;
2138
+ /** The initial message describing the issue (max 2000 chars) */
2139
+ message: string;
2140
+ /** Ticket category (default: OTHER) */
2141
+ category?: SupportTicketCategory;
2142
+ /** Optional contact email */
2143
+ email?: string;
2144
+ }
2145
+ interface GetTicketsOptions {
2146
+ page?: number;
2147
+ limit?: number;
2148
+ status?: SupportTicketStatus;
2149
+ category?: SupportTicketCategory;
2150
+ }
2151
+ interface UpdateTicketData {
2152
+ status?: SupportTicketStatus;
2153
+ priority?: SupportTicketPriority;
2154
+ }
2155
+ declare class Support {
2156
+ private http;
2157
+ private logger?;
2158
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2159
+ /**
2160
+ * Create a new support ticket (authenticated users)
2161
+ * Rate limited to 5 tickets per hour.
2162
+ * @param data - Ticket data (message required, subject/category/email optional)
2163
+ */
2164
+ create(data: CreateTicketData): Promise<SupportTicket>;
2165
+ /**
2166
+ * Get my support tickets (paginated)
2167
+ * @param options - Pagination and filter options
2168
+ */
2169
+ getMyTickets(options?: GetTicketsOptions): Promise<PaginatedSupportTickets>;
2170
+ /**
2171
+ * Get a specific ticket with all messages (user can only see own)
2172
+ * @param ticketId - The ticket ID
2173
+ */
2174
+ getMyTicketById(ticketId: string): Promise<SupportTicket>;
2175
+ /**
2176
+ * Add a message to an existing ticket (user can only message own)
2177
+ * @param ticketId - The ticket ID
2178
+ * @param message - Message content (max 2000 chars)
2179
+ */
2180
+ addMessage(ticketId: string, message: string): Promise<SupportMessage>;
2181
+ /**
2182
+ * Close a ticket (user can close own)
2183
+ * @param ticketId - The ticket ID
2184
+ */
2185
+ closeTicket(ticketId: string): Promise<SupportTicket>;
2186
+ /**
2187
+ * Get all support tickets (admin only, paginated)
2188
+ * @param options - Pagination and filter options
2189
+ */
2190
+ list(options?: GetTicketsOptions): Promise<PaginatedSupportTickets>;
2191
+ /**
2192
+ * Get open ticket count (admin only)
2193
+ */
2194
+ getOpenCount(): Promise<{
2195
+ count: number;
2196
+ }>;
2197
+ /**
2198
+ * Get a single ticket by ID (admin only)
2199
+ * @param ticketId - The ticket ID
2200
+ */
2201
+ getById(ticketId: string): Promise<SupportTicket>;
2202
+ /**
2203
+ * Update ticket status/priority (admin only)
2204
+ * @param ticketId - The ticket ID
2205
+ * @param data - Update data (status and/or priority)
2206
+ */
2207
+ update(ticketId: string, data: UpdateTicketData): Promise<SupportTicket>;
2208
+ /**
2209
+ * Reply to a ticket as admin (admin only)
2210
+ * @param ticketId - The ticket ID
2211
+ * @param message - Reply content (max 2000 chars)
2212
+ */
2213
+ reply(ticketId: string, message: string): Promise<SupportMessage>;
2214
+ /**
2215
+ * Delete a ticket (admin only)
2216
+ * @param ticketId - The ticket ID
2217
+ */
2218
+ delete(ticketId: string): Promise<void>;
2219
+ }
2220
+
2221
+ interface MarketState {
2222
+ marketId: string;
2223
+ gameId: string;
2224
+ status: string;
2225
+ outcomes: string[];
2226
+ prices: Record<string, number>;
2227
+ totalCollateral: string;
2228
+ totalVolume: string;
2229
+ totalFees: string;
2230
+ resolvedOutcome: string | null;
2231
+ }
2232
+ interface MarketPosition {
2233
+ outcomeId: string;
2234
+ shares: string;
2235
+ avgCostPerShare: string;
2236
+ totalCost: string;
2237
+ currentPrice: number;
2238
+ currentValue: string;
2239
+ unrealizedPnl: string;
2240
+ }
2241
+ interface MarketBuyResult {
2242
+ tradeId: string;
2243
+ sharesReceived: string;
2244
+ costPerShare: string;
2245
+ newPrices: Record<string, number>;
2246
+ }
2247
+ interface MarketSellResult {
2248
+ tradeId: string;
2249
+ amountReceived: string;
2250
+ pricePerShare: string;
2251
+ newPrices: Record<string, number>;
2252
+ }
2253
+ interface RedeemResult {
2254
+ status: string;
2255
+ payout: string;
2256
+ fee: string;
2257
+ netPayout: string;
2258
+ profit: string;
2259
+ }
2260
+ interface AdminMarketStats {
2261
+ totalMarkets: number;
2262
+ openMarkets: number;
2263
+ resolvedMarkets: number;
2264
+ totalVolume: string;
2265
+ totalFees: string;
2266
+ uniqueTraders: number;
2267
+ }
2268
+ interface AdminMarketDailyStatsItem {
2269
+ date: string;
2270
+ marketsOpened: number;
2271
+ marketsResolved: number;
2272
+ tradesExecuted: number;
2273
+ volume: string;
2274
+ fees: string;
2275
+ }
2276
+ interface AdminMarketDailyStats {
2277
+ days: AdminMarketDailyStatsItem[];
2278
+ }
2279
+ interface AdminMarketDetail {
2280
+ id: string;
2281
+ gameId: string;
2282
+ status: string;
2283
+ outcomes: string[];
2284
+ resolvedOutcome: string | null;
2285
+ totalCollateral: string;
2286
+ totalVolume: string;
2287
+ totalFees: string;
2288
+ createdAt: string;
2289
+ resolvedAt: string | null;
2290
+ positionCount: number;
2291
+ }
2292
+ /**
2293
+ * SDK class for prediction market operations.
2294
+ *
2295
+ * @example
2296
+ * ```ts
2297
+ * const market = await sdk.markets.getMarket(gameId);
2298
+ * console.log(market.prices); // { playerAId: 0.6, playerBId: 0.4 }
2299
+ *
2300
+ * const { transaction } = await sdk.markets.prepareBuyOrder(gameId, playerAId, 1_000_000);
2301
+ * // ... sign transaction ...
2302
+ * const result = await sdk.markets.submitBuyOrder(gameId, signedTxBase64, playerAId, 1_000_000);
2303
+ * console.log(result.sharesReceived);
2304
+ * ```
2305
+ */
2306
+ declare class Markets {
2307
+ private http;
2308
+ private logger?;
2309
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2310
+ /**
2311
+ * Get the prediction market state for a game.
2312
+ * Returns prices, volume, collateral, and resolution status.
2313
+ */
2314
+ getMarket(gameId: string): Promise<MarketState>;
2315
+ /**
2316
+ * Get the authenticated user's positions for a game.
2317
+ * Returns shares held, average cost, current value, and unrealized P&L.
2318
+ */
2319
+ getMyPositions(gameId: string): Promise<MarketPosition[]>;
2320
+ /**
2321
+ * Prepare a buy order deposit transaction (unsigned, for client signing).
2322
+ * @param gameId - The game ID
2323
+ * @param outcomeId - The outcome to buy (typically a player ID)
2324
+ * @param amountMinor - Amount to spend in USDC minor units
2325
+ */
2326
+ prepareBuyOrder(gameId: string, outcomeId: string, amountMinor: number): Promise<{
2327
+ transaction: string;
2328
+ }>;
2329
+ /**
2330
+ * Submit a signed buy order deposit transaction and execute the trade.
2331
+ * Shares are received instantly via the AMM pool.
2332
+ * @param gameId - The game ID
2333
+ * @param signedTransaction - Base64-encoded signed Solana transaction
2334
+ * @param outcomeId - The outcome to buy (typically a player ID)
2335
+ * @param amountMinor - Amount to spend in USDC minor units
2336
+ */
2337
+ submitBuyOrder(gameId: string, signedTransaction: string, outcomeId: string, amountMinor: number): Promise<MarketBuyResult>;
2338
+ /**
2339
+ * Sell shares back to the AMM pool.
2340
+ * @param gameId - The game ID
2341
+ * @param outcomeId - The outcome to sell
2342
+ * @param shares - Number of shares to sell (in minor units)
2343
+ */
2344
+ sellShares(gameId: string, outcomeId: string, shares: number): Promise<MarketSellResult>;
2345
+ /**
2346
+ * Redeem winning shares after a market is resolved.
2347
+ * @param gameId - The game ID
2348
+ */
2349
+ redeemShares(gameId: string): Promise<RedeemResult>;
2350
+ /**
2351
+ * Get aggregate prediction market stats.
2352
+ * Requires admin privileges.
2353
+ */
2354
+ getAdminStats(): Promise<AdminMarketStats>;
2355
+ /**
2356
+ * Get daily prediction market stats breakdown.
2357
+ * Requires admin privileges.
2358
+ * @param days - Number of days to look back (default 30)
2359
+ */
2360
+ getAdminDailyStats(days?: number): Promise<AdminMarketDailyStats>;
2361
+ /**
2362
+ * List all prediction markets with position counts.
2363
+ * Requires admin privileges.
2364
+ */
2365
+ getAdminMarkets(page?: number, limit?: number): Promise<{
2366
+ markets: AdminMarketDetail[];
2367
+ total: number;
2368
+ }>;
2369
+ }
2370
+
2371
+ type LobbyMatchedEvent = {
2372
+ gameId: string;
2373
+ gameType: string;
2374
+ matchedLobbies: Lobby[];
2375
+ };
2376
+ type LobbyStoreState = {
2377
+ lobbiesById: Record<string, Lobby>;
2378
+ matchedEvent: LobbyMatchedEvent | null;
2379
+ typingByLobbyId: Record<string, string[]>;
2380
+ };
2381
+ type LobbyStore = {
2382
+ store: SdkStore<LobbyStoreState>;
2383
+ setBaseState: (lobbies: Lobby[]) => void;
2384
+ applyWsEvent: (event: WsEvent) => void;
2385
+ joinLobby: (lobbyId: string) => () => void;
2386
+ subscribeMatched: (callback: (event: LobbyMatchedEvent) => void) => () => void;
2387
+ };
2388
+ declare function createLobbyStore(transport: WsTransport): LobbyStore;
2389
+
2390
+ type GameStoreState = {
2391
+ gamesById: Record<string, Game>;
2392
+ /** Real-time spectator counts by userId, updated via spectator:count:updated WS events. */
2393
+ spectatorCounts: Record<string, number>;
2394
+ };
2395
+ type GameStore = {
2396
+ store: SdkStore<GameStoreState>;
2397
+ setBaseState: (games: Game[]) => void;
2398
+ applyWsEvent: (event: WsEvent) => void;
2399
+ joinGame: (gameId: string) => () => void;
2400
+ /** Join the spectate channel for a user. Returns a leave function. */
2401
+ joinSpectateChannel: (spectatedUserId: string) => () => void;
2402
+ /** Get a snapshot of the spectator count for a user (from the store). */
2403
+ getSpectatorCount: (userId: string) => number;
2404
+ };
2405
+ declare function createGameStore(transport: WsTransport): GameStore;
2406
+
2407
+ type GameActionsStoreState = {
2408
+ statesByGameId: Record<string, GameStateResponse>;
2409
+ };
2410
+ type GameActionsStore = {
2411
+ store: SdkStore<GameActionsStoreState>;
2412
+ setBaseState: (gameId: string, state: GameStateResponse) => void;
2413
+ clearState: (gameId: string) => void;
2414
+ applyWsEvent: (event: WsEvent) => void;
2415
+ joinGame: (gameId: string) => () => void;
2416
+ };
2417
+ declare function createGameActionsStore(transport: WsTransport): GameActionsStore;
2418
+
2419
+ interface TypingUser {
2420
+ userId: string;
2421
+ username?: string;
2422
+ }
2423
+ interface ChatState {
2424
+ context: ChatContext;
2425
+ messages: ChatMessage[];
2426
+ typingUsers: TypingUser[];
2427
+ }
2428
+ type ChatStoreState = {
2429
+ contextsByKey: Record<string, ChatState>;
2430
+ };
2431
+ type ChatStore = {
2432
+ store: SdkStore<ChatStoreState>;
2433
+ setMessages: (context: ChatContext, messages: ChatMessage[]) => void;
2434
+ applyWsEvent: (event: WsEvent) => void;
2435
+ joinContext: (context: ChatContext) => () => void;
2436
+ leaveContext: (context: ChatContext) => void;
2437
+ };
2438
+ declare function createChatStore(transport: WsTransport): ChatStore;
2439
+
2440
+ type DmThreadsStoreState = {
2441
+ threads: DmThread[];
2442
+ loading: boolean;
2443
+ error: string | null;
2444
+ needsRefresh: boolean;
2445
+ };
2446
+ type DmThreadsStore = {
2447
+ store: SdkStore<DmThreadsStoreState>;
2448
+ setBaseState: (threads: DmThread[]) => void;
2449
+ setLoading: (loading: boolean) => void;
2450
+ setError: (error: string | null) => void;
2451
+ setCurrentUserId: (userId: string | null) => void;
2452
+ applyWsEvent: (event: WsEvent) => void;
2453
+ };
2454
+ declare function createDmThreadsStore(): DmThreadsStore;
2455
+
2456
+ type FriendshipStatus = 'none' | 'incoming' | 'outgoing' | 'friends';
2457
+ type FriendsStoreState = {
2458
+ /** Optimistic overrides keyed by userId. Only set when status differs from API (e.g. 'outgoing' after send, cleared when API data arrives). */
2459
+ friendshipStatusOverrides: Record<string, FriendshipStatus>;
2460
+ };
2461
+ type FriendsStore = {
2462
+ store: SdkStore<FriendsStoreState>;
2463
+ setOptimisticStatus: (userId: string, status: FriendshipStatus) => void;
2464
+ clearOverride: (userId: string) => void;
2465
+ clearOverridesForUsers: (userIds: string[]) => void;
2466
+ };
2467
+ declare function createFriendsStore(): FriendsStore;
2468
+
2469
+ interface SdkUpgradeInfo {
2470
+ message: string;
2471
+ minSdkVersion: string;
2472
+ }
2473
+ declare class WsEventBus {
2474
+ private transport;
2475
+ private upgradeHandlers;
2476
+ private upgradeUnsubscribe;
2477
+ constructor(transport: WsTransport);
2478
+ subscribe<T>(eventName: string, handler: (payload: T) => void): () => void;
2479
+ /**
2480
+ * Register a handler to be called when the server recommends an SDK upgrade.
2481
+ * Returns an unsubscribe function.
2482
+ */
2483
+ onUpgradeRecommended(handler: (info: SdkUpgradeInfo) => void): () => void;
2484
+ }
2485
+
2486
+ declare class SDK {
2487
+ private http;
2488
+ auth: Auth;
2489
+ admin: Admin;
2490
+ users: Users;
2491
+ featureFlags: FeatureFlags;
2492
+ lobbies: Lobbies;
2493
+ games: Games;
2494
+ spectate: Spectate;
2495
+ chat: Chat;
2496
+ challenges: Challenges;
2497
+ tips: Tips;
2498
+ daily: Daily;
2499
+ activity: Activity;
2500
+ leaderboards: Leaderboards;
2501
+ notifications: Notifications;
2502
+ achievements: Achievements;
2503
+ wallet: Wallet;
2504
+ escrow: Escrow;
2505
+ referrals: Referrals;
2506
+ reports: Reports;
2507
+ support: Support;
2508
+ markets: Markets;
2509
+ wsTransport: WsTransport;
2510
+ lobbyStore: LobbyStore;
2511
+ gameStore: GameStore;
2512
+ gameActionsStore: GameActionsStore;
2513
+ chatStore: ChatStore;
2514
+ dmThreadsStore: DmThreadsStore;
2515
+ notificationsStore: NotificationsStore;
2516
+ friendsStore: FriendsStore;
2517
+ events: WsEventBus;
2518
+ private wsRouter;
2519
+ constructor(config: SDKConfig);
2520
+ /**
2521
+ * Ensure the shared WebSocket connection is established.
2522
+ *
2523
+ * Some backend operations (e.g. joining the matchmaking queue) require the user
2524
+ * to be connected to the app via WebSocket.
2525
+ */
2526
+ ensureWebSocketConnected(timeoutMs?: number): Promise<void>;
2527
+ }
2528
+
2529
+ /**
2530
+ * SDK version constant.
2531
+ *
2532
+ * This must be kept in sync with the version in package.json.
2533
+ * Sent to the API via the `X-SDK-Version` header on every HTTP request
2534
+ * and in the Socket.IO handshake auth.
2535
+ */
2536
+ declare const SDK_VERSION = "1.0.0";
2537
+
2538
+ declare abstract class BaseWsTransport implements WsTransport {
2539
+ private roomRefs;
2540
+ private waiters;
2541
+ protected connectionState: ConnectionState;
2542
+ protected appId: string | null;
2543
+ abstract connect(): void;
2544
+ abstract disconnect(): void;
2545
+ abstract setAccessToken(token: string): void;
2546
+ abstract clearAccessToken(): void;
2547
+ abstract subscribeEvent(eventName: string, handler: (payload: unknown) => void): () => void;
2548
+ abstract subscribeAll(handler: (event: string, payload: unknown) => void): () => void;
2549
+ abstract emit(eventName: string, payload?: unknown): void;
2550
+ setAppId(appId: string): void;
2551
+ getConnectionState(): ConnectionState;
2552
+ resetRooms(): void;
2553
+ joinRoom(roomName: string): () => void;
2554
+ waitUntilConnected(timeoutMs?: number): Promise<void>;
2555
+ protected updateConnectionState(next: Partial<ConnectionState>): void;
2556
+ protected handleAuthFailure(message?: string): void;
2557
+ protected onReconnect(): void;
2558
+ protected abstract onJoinRoom(roomName: string): void;
2559
+ protected abstract onLeaveRoom(roomName: string): void;
2560
+ private leaveRoom;
2561
+ }
2562
+
2563
+ declare class StandaloneWsTransport extends BaseWsTransport {
2564
+ private socket;
2565
+ private url;
2566
+ private accessToken;
2567
+ private reconnectAttempts;
2568
+ private reconnectTimer;
2569
+ private maxReconnectAttempts;
2570
+ private reconnectDelay;
2571
+ private reconnectDelayMax;
2572
+ private wildcardHandlers;
2573
+ private eventHandlers;
2574
+ private registeredEvents;
2575
+ private wildcardRegistered;
2576
+ constructor(url: string);
2577
+ connect(): void;
2578
+ disconnect(): void;
2579
+ setAccessToken(token: string): void;
2580
+ clearAccessToken(): void;
2581
+ subscribeEvent(eventName: string, handler: WsEventHandler): () => void;
2582
+ subscribeAll(handler: WsWildcardHandler): () => void;
2583
+ emit(eventName: string, payload?: unknown): void;
2584
+ protected onJoinRoom(roomName: string): void;
2585
+ protected onLeaveRoom(roomName: string): void;
2586
+ private ensureSocket;
2587
+ private reconnectWithAuth;
2588
+ private scheduleReconnect;
2589
+ private getEventHandlers;
2590
+ private unsubscribeEvent;
2591
+ private unsubscribeAll;
2592
+ private dispatchEvent;
2593
+ private dispatchWildcard;
2594
+ private registerEventHandler;
2595
+ private registerWildcard;
2596
+ }
2597
+
2598
+ declare class SharedWorkerTransport extends BaseWsTransport {
2599
+ private client;
2600
+ private url;
2601
+ constructor(workerUrl: string, socketUrl: string);
2602
+ connect(): void;
2603
+ disconnect(): void;
2604
+ setAccessToken(token: string): void;
2605
+ clearAccessToken(): void;
2606
+ setAppId(appId: string): void;
2607
+ subscribeEvent(eventName: string, handler: WsEventHandler): () => void;
2608
+ subscribeAll(handler: WsWildcardHandler): () => void;
2609
+ emit(eventName: string, payload?: unknown): void;
2610
+ protected onJoinRoom(roomName: string): void;
2611
+ protected onLeaveRoom(roomName: string): void;
2612
+ private handleWorkerMessage;
2613
+ }
2614
+
2615
+ declare class HttpClient implements IHttpClient {
2616
+ private baseUrl;
2617
+ private storage;
2618
+ private logger;
2619
+ private appId?;
2620
+ constructor(baseUrl: string, storage: IStorage, logger?: ILogger, appId?: string);
2621
+ request<T>(endpoint: string, options?: RequestInit): Promise<T>;
2622
+ get<T>(endpoint: string, options?: RequestInit): Promise<T>;
2623
+ post<T>(endpoint: string, data?: any, options?: RequestInit): Promise<T>;
2624
+ patch<T>(endpoint: string, data?: any, options?: RequestInit): Promise<T>;
2625
+ delete<T>(endpoint: string, options?: RequestInit): Promise<T>;
2626
+ upload<T>(endpoint: string, formData: FormData): Promise<T>;
2627
+ }
2628
+
2629
+ export { type AcceptChallengeResponse, type Achievement, Activity, type ActivityFeedItem, type ActivityFeedItemType, type ActivityFeedResponse, type ActivityFeedUser, Admin, type AdminDailyStats, type AdminDailyStatsItem, type AdminGameHistory, type AdminGameHistoryFeeBreakdown, type AdminGameHistoryFeePlayer, type AdminGameHistoryPlayer, type AdminMarketDailyStats, type AdminMarketDailyStatsItem, type AdminMarketDetail, type AdminMarketStats, type AdminStats, type AdminWalletActivityItem, type AdminWalletActivityResponse, type ApiError, type AppNotification, type AppNotificationType, type ApplyReferralCodeResponse, type BalanceResponse, type BetOption, type BroadcastTipRequest, BrowserLocalStorage, Challenges, Chat, type ChatContext, type ChatContextType, type ChatMessage, type ChatMessageReply, type ChatMessageType, type ChatReaction, type ChatReadBy, type ChatState, type ChatStore, type ChatStoreState, type ClaimReferralRewardsResponse, type CreateChallengeRequest, type CreateChallengeResponse, type CreateLobbyRequest, type CreateTicketData, type CriticalIncident, type CriticalIncidentCategory, type CriticalIncidentImpactType, type CriticalIncidentSeverity, type CriticalIncidentStatus, type CriticalIncidentSummary, type CurrentGame, Daily, type DailyParticipant, type DailyRoom, type DailyToken, type DepositStatus, type DepositStatusResponse, type DmThread, type DmThreadsStore, type DmThreadsStoreState, type DonateToGameResponse, ESTIMATED_SOL_FEE_LAMPORTS, Escrow, type EscrowSweepPreview, type EscrowSweepRecord, type FaucetResponse, type FeatureFlag, type FriendRequestItem, type FriendsStore, type FriendsStoreState, type FriendshipStatus, type Game, type GameActionsStore, type GameActionsStoreState, type GameHistoryItem, type GameMetrics, type GamePlayer, type GameStateResponse, type GameStore, type GameStoreState, type GameType, Games, type GenerateHandshakeResponse, type GetTicketsOptions, HttpClient, type IHttpClient, type ILogger, type IStorage, type InviteFriendRequest, type LeaderboardEntry, type LeaderboardQuery, type LeaderboardRange, type LeaderboardResponse, Leaderboards, type LivePlayer, type LivePlayersPage, Lobbies, type Lobby, type LobbyMatchedEvent, type LobbyPlayer, type LobbyStore, type LobbyStoreState, type LogLevel, type LoginResponse, MIN_SOL_TRANSFER_AMOUNT, MIN_TRANSFER_AMOUNT, type MarketBuyResult, type MarketPosition, type MarketSellResult, type MarketState, Markets, type MoneyMinor, NodeStorage, type NotificationEvent, type NotificationsStore, type NotificationsStoreState, type PaginatedCriticalIncidents, type PaginatedFriends, type PaginatedNotificationsResponse, type PaginatedReports, type PaginatedSearchUsers, type PaginatedSessions, type PaginatedSupportTickets, type PaginatedUsers, type PrepareDepositResponse, type PrepareTipRequest, type PrepareTipResponse, type PrepareTransferRequest, type PrepareTransferResponse, type PublicUser, type QueueStats, type RedeemResult, type ReferralRewardItem, type ReferralRewardStatus, type ReferralRewardsResponse, type ReferralSummary, type ReferralTreeItem, type ReferralTreeResponse, Referrals, type Report, type ReportCount, type ReportStatus, type ReportUser, Reports, type RetryOptions, SDK, type SDKConfig, SDK_VERSION, SOL_DECIMALS, SOL_MINT, type SdkStore, type SdkUpgradeInfo, type SearchUser, type SendMessageRequest, type SendTipResponse, type SendTransferResponse, type Session, SharedWorkerTransport, Spectate, type SpectatorMetrics, type SpectatorMetricsByUser, StandaloneWsTransport, type SubmitDepositResponse, type SubmitTransferRequest, type SubmitTransferResponse, Support, type SupportMessage, type SupportMessageSenderRole, type SupportTicket, type SupportTicketCategory, type SupportTicketPriority, type SupportTicketStatus, type SupportTicketUser, type SystemMessageType, TOKEN_KEY, TRANSFER_FEE_MINOR, Tips, type TransferToken, type TypingUser, type UpdateTicketData, type User, type UserAchievement, type UserActivity, type UserActivityStatus, type UserStats, type UsernameAvailabilityResponse, Users, type ValidAction, Wallet, type WalletActivityCounterpartyType, type WalletActivityDirection, type WalletActivityItem, type WalletActivityKind, type WalletActivityResponse, type WalletActivityStatus, type WalletClaimAction, type WalletMeta, type WalletResponse, type WalletSigner, type WsEvent, WsEventBus, type WsEventName, type WsTransport, type ConnectionState as WsTransportState, createChatStore, createDmThreadsStore, createFriendsStore, createGameActionsStore, createGameStore, createLobbyStore, createLogger, createNotificationsStore, createSdkStore, isRetryableError, logger, withRetry };