@dimcool/sdk 0.1.29 → 0.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
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';
2
+ import { RpsGameState, RpsGameAction, RpsAction } from '@dimcool/rps';
3
+ import { ChessGameState, ChessGameAction, ChessMovePayload } from '@dimcool/chess';
4
+ import { NimGameState, NimGameAction } from '@dimcool/nim';
5
+ import { DotsAndBoxesGameState, DotsAndBoxesGameAction } from '@dimcool/dots-and-boxes';
6
+ import { TicTacToeGameState, TicTacToeGameAction } from '@dimcool/tic-tac-toe';
7
+ import { Connect4GameState, Connect4GameAction } from '@dimcool/connect-four';
8
8
  export { MICRO_UNITS, formatMoneyMinor, toMajor } from '@dimcool/utils';
9
9
 
10
10
  /**
@@ -108,6 +108,62 @@ interface ConnectionState {
108
108
  error: string | null;
109
109
  }
110
110
 
111
+ interface AnalyticsUserData {
112
+ userId: string;
113
+ username?: string | null;
114
+ email?: string | null;
115
+ walletAddress?: string | null;
116
+ authProvider?: 'google' | 'apple' | 'injected' | 'keypair';
117
+ isBot?: boolean;
118
+ createdAt?: string;
119
+ }
120
+ interface IAnalyticsClient {
121
+ /**
122
+ * Called after a successful login. Implementations should identify the user
123
+ * and link any pre-login anonymous events to their profile.
124
+ */
125
+ userLoggedIn(user: AnalyticsUserData, meta: {
126
+ isNewUser: boolean;
127
+ authMethod: string;
128
+ referralCode?: string;
129
+ }): void;
130
+ /**
131
+ * Called on logout. Implementations should reset the current identity so
132
+ * subsequent events are associated with a new anonymous session.
133
+ */
134
+ userLoggedOut(): void;
135
+ /**
136
+ * Called on app boot when auth is restored from storage (returning user).
137
+ * Should re-attach the user identity without creating a new alias link.
138
+ */
139
+ sessionRestored(user: AnalyticsUserData): void;
140
+ /**
141
+ * Track a discrete event. Fire-and-forget — must never throw or block.
142
+ */
143
+ track(event: string, properties?: Record<string, unknown>): void;
144
+ /**
145
+ * Set persistent user properties that will be attached to the user's profile.
146
+ */
147
+ setUserProperties(properties: Record<string, unknown>): void;
148
+ /**
149
+ * Associate the current user with a group (e.g. game_type).
150
+ */
151
+ group(groupType: string, groupKey: string, properties?: Record<string, unknown>): void;
152
+ }
153
+ /** Default noop implementation — used when no analytics client is configured. */
154
+ declare class NoopAnalyticsClient implements IAnalyticsClient {
155
+ userLoggedIn(_user: AnalyticsUserData, _meta: {
156
+ isNewUser: boolean;
157
+ authMethod: string;
158
+ referralCode?: string;
159
+ }): void;
160
+ userLoggedOut(): void;
161
+ sessionRestored(_user: AnalyticsUserData): void;
162
+ track(_event: string, _properties?: Record<string, unknown>): void;
163
+ setUserProperties(_properties: Record<string, unknown>): void;
164
+ group(_groupType: string, _groupKey: string, _properties?: Record<string, unknown>): void;
165
+ }
166
+
111
167
  interface SDKConfig {
112
168
  appId: string;
113
169
  baseUrl?: string;
@@ -115,6 +171,7 @@ interface SDKConfig {
115
171
  httpClient?: IHttpClient;
116
172
  wsTransport?: WsTransport;
117
173
  logger?: ILogger;
174
+ analytics?: IAnalyticsClient;
118
175
  autoPay?: {
119
176
  enabled?: boolean;
120
177
  maxAmountMinor?: number;
@@ -207,6 +264,9 @@ interface FeatureFlag {
207
264
  createdAt: string;
208
265
  updatedAt: string;
209
266
  }
267
+ interface AdminFeatureFlag extends FeatureFlag {
268
+ description: string | null;
269
+ }
210
270
  interface ApiError {
211
271
  error?: string;
212
272
  message?: string | string[];
@@ -216,6 +276,7 @@ interface ApiError {
216
276
  interface UsernameAvailabilityResponse {
217
277
  valid: boolean;
218
278
  available: boolean;
279
+ reason?: 'reserved' | 'taken' | 'invalid_format' | 'blocked_domain';
219
280
  }
220
281
  interface PublicUser {
221
282
  id: string;
@@ -259,6 +320,10 @@ interface FriendRequestItem {
259
320
  mutualFriendsCount: number;
260
321
  createdAt: string;
261
322
  }
323
+ interface PaginatedFriendRequests {
324
+ items: FriendRequestItem[];
325
+ nextCursor?: string;
326
+ }
262
327
  interface PaginatedSearchUsers {
263
328
  users: SearchUser[];
264
329
  total: number;
@@ -284,6 +349,22 @@ interface PaginatedSessions {
284
349
  sessions: Session[];
285
350
  total: number;
286
351
  }
352
+ interface SessionStats {
353
+ total: number;
354
+ email: number;
355
+ wallet: number;
356
+ walletBreakdown: {
357
+ phantomEmbedded: number;
358
+ keypair: number;
359
+ byProvider: {
360
+ google: number;
361
+ apple: number;
362
+ injected: number;
363
+ unknown: number;
364
+ };
365
+ byWalletName: Record<string, number>;
366
+ };
367
+ }
287
368
  type ActivityFeedItemType = 'new_user' | 'win' | 'lobby_created' | 'game_started';
288
369
  interface ActivityFeedUser {
289
370
  id: string;
@@ -996,6 +1077,16 @@ declare class Wallet {
996
1077
  * Confirm a transfer that was already sent by the client (signAndSendTransaction path).
997
1078
  */
998
1079
  confirmTransferSignature(signature: string, senderAddress: string, recipientAddress: string, amount: number, token?: TransferToken, ataCreated?: boolean, recipientInput?: string): Promise<SubmitTransferResponse>;
1080
+ /**
1081
+ * Sign a prepared transaction and invoke the appropriate backend callback
1082
+ * based on the configured signer — without exposing the mode decision to callers.
1083
+ * - Embedded wallet (signAndSend): signs+sends, calls onSignedAndSent(signature)
1084
+ * - Injected wallet (signTransaction): signs locally, calls onSigned(signedTxBase64)
1085
+ */
1086
+ signAndDispatch<T>(unsignedTxBase64: string, handlers: {
1087
+ onSigned: (signedTxBase64: string) => Promise<T>;
1088
+ onSignedAndSent: (signature: string) => Promise<T>;
1089
+ }): Promise<T>;
999
1090
  /**
1000
1091
  * Full transfer flow in one call: prepare -> sign -> submit
1001
1092
  * Recipient can be username, .sol domain, or Solana address (resolved by backend).
@@ -1011,13 +1102,18 @@ declare class Auth {
1011
1102
  private logger;
1012
1103
  constructor(http: IHttpClient, storage: IStorage, wallet: Wallet, logger?: ILogger);
1013
1104
  login(email: string, password: string): Promise<LoginResponse>;
1014
- private generateHandshake;
1105
+ generateHandshake(walletAddress: string): Promise<GenerateHandshakeResponse>;
1015
1106
  loginWithWallet(options?: {
1016
1107
  referralCode?: string;
1017
1108
  walletMeta?: WalletMeta;
1018
1109
  }): Promise<LoginResponse>;
1110
+ loginWithExternalSignature(address: string, signedMessage: string, options?: {
1111
+ referralCode?: string;
1112
+ walletMeta?: WalletMeta;
1113
+ }): Promise<LoginResponse>;
1019
1114
  logout(): void;
1020
1115
  isAuthenticated(): boolean;
1116
+ getSessionStats(): Promise<SessionStats>;
1021
1117
  getLatestSessions(limit?: number): Promise<PaginatedSessions>;
1022
1118
  }
1023
1119
 
@@ -1108,8 +1204,14 @@ declare class Users {
1108
1204
  removeFriend(userId: string): Promise<{
1109
1205
  message: string;
1110
1206
  }>;
1111
- getIncomingFriendRequests(): Promise<FriendRequestItem[]>;
1112
- getOutgoingFriendRequests(): Promise<FriendRequestItem[]>;
1207
+ getIncomingFriendRequests(opts?: {
1208
+ limit?: number;
1209
+ cursor?: string;
1210
+ }): Promise<PaginatedFriendRequests>;
1211
+ getOutgoingFriendRequests(opts?: {
1212
+ limit?: number;
1213
+ cursor?: string;
1214
+ }): Promise<PaginatedFriendRequests>;
1113
1215
  acceptFriendRequest(userId: string): Promise<{
1114
1216
  message: string;
1115
1217
  }>;
@@ -1159,134 +1261,188 @@ declare class FeatureFlags {
1159
1261
  private loaded;
1160
1262
  constructor(http: IHttpClient, logger?: ILogger | undefined);
1161
1263
  getFeatureFlags(): Promise<FeatureFlag[]>;
1264
+ getAdminFeatureFlags(): Promise<AdminFeatureFlag[]>;
1162
1265
  isEnabledFlag(name: string): boolean;
1163
1266
  isLoaded(): boolean;
1164
1267
  updateFeatureFlag(name: string, enabled: boolean): Promise<FeatureFlag>;
1165
- createFeatureFlag(name: string, enabled: boolean): Promise<FeatureFlag>;
1268
+ createFeatureFlag(name: string, enabled: boolean, description?: string): Promise<AdminFeatureFlag>;
1166
1269
  }
1167
1270
 
1168
- interface BetOption {
1169
- amount: MoneyMinor;
1170
- playersOnline: number;
1171
- estimatedTime: string;
1172
- }
1173
- interface LobbyPlayer {
1174
- userId: string;
1175
- username?: string;
1176
- avatar?: string;
1177
- joinedAt: string;
1178
- connected?: boolean;
1179
- /** USDC balance in minor units (cached, short TTL). Shown in lobby and used to gate Start Game. */
1180
- usdcBalance?: number;
1181
- }
1182
- interface Lobby {
1183
- id: string;
1184
- gameType: string;
1185
- gameName: string;
1186
- status: 'waiting' | 'preparing' | 'queued' | 'active';
1187
- creatorId: string;
1188
- maxPlayers: number;
1189
- betAmount?: MoneyMinor;
1190
- betOptions?: BetOption[];
1191
- gameId?: string;
1192
- createdAt: string;
1193
- updatedAt: string;
1194
- players: LobbyPlayer[];
1195
- }
1196
- interface CreateLobbyRequest {
1197
- gameType: string;
1198
- }
1199
- interface InviteFriendRequest {
1200
- friendId: string;
1271
+ /**
1272
+ * Retry configuration options
1273
+ */
1274
+ interface RetryOptions {
1275
+ /** Maximum number of retry attempts (default: 3) */
1276
+ maxAttempts?: number;
1277
+ /** Base delay in milliseconds (default: 1000) */
1278
+ baseDelayMs?: number;
1279
+ /** Maximum delay in milliseconds (default: 10000) */
1280
+ maxDelayMs?: number;
1281
+ /** Multiplier for exponential backoff (default: 2) */
1282
+ backoffMultiplier?: number;
1283
+ /** Function to determine if error is retryable (default: network/5xx errors) */
1284
+ isRetryable?: (error: unknown) => boolean;
1285
+ /** Callback for each retry attempt */
1286
+ onRetry?: (attempt: number, error: unknown, delayMs: number) => void;
1201
1287
  }
1202
- interface QueueStats {
1203
- totalPlayersInQueue: number;
1204
- queueSizes: Record<string, number>;
1205
- totalQueuedLobbies: number;
1288
+ /**
1289
+ * Default function to determine if an error is retryable.
1290
+ * Retries on network errors and 5xx server errors.
1291
+ */
1292
+ declare function isRetryableError(error: unknown): boolean;
1293
+ /**
1294
+ * Execute an async function with exponential backoff retry.
1295
+ *
1296
+ * @param fn - Async function to execute
1297
+ * @param options - Retry configuration
1298
+ * @returns Promise resolving to the function result
1299
+ * @throws Last error if all retries exhausted
1300
+ *
1301
+ * @example
1302
+ * ```typescript
1303
+ * const result = await withRetry(
1304
+ * () => fetch('/api/data'),
1305
+ * { maxAttempts: 3, baseDelayMs: 500 }
1306
+ * );
1307
+ * ```
1308
+ */
1309
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1310
+
1311
+ type EqualityFn<T> = (a: T, b: T) => boolean;
1312
+ interface SdkStore<S> {
1313
+ getSnapshot(): S;
1314
+ getState(): S;
1315
+ setState(next: S): void;
1316
+ updateState(updater: (prev: S) => S): void;
1317
+ subscribe(listener: () => void): () => void;
1318
+ subscribeSelector<T>(selector: (state: S) => T, listener: () => void, isEqual?: EqualityFn<T>): () => void;
1206
1319
  }
1207
- type ChatMessageType = 'user' | 'system';
1208
- type SystemMessageType = 'player_joined' | 'player_left' | 'bet_changed' | 'call_joined' | 'call_left' | 'global_help' | 'global_challenge' | 'global_tip' | 'spectator_donation' | 'challenge_accepted' | 'challenge_declined';
1209
- interface ChatMessageReply {
1320
+ declare function createSdkStore<S>(initial: S): SdkStore<S>;
1321
+
1322
+ type DmThreadsStoreState = {
1323
+ threads: DmThread[];
1324
+ loading: boolean;
1325
+ error: string | null;
1326
+ needsRefresh: boolean;
1327
+ };
1328
+ type DmThreadsStore = {
1329
+ store: SdkStore<DmThreadsStoreState>;
1330
+ setBaseState: (threads: DmThread[]) => void;
1331
+ setLoading: (loading: boolean) => void;
1332
+ setError: (error: string | null) => void;
1333
+ setCurrentUserId: (userId: string | null) => void;
1334
+ applyWsEvent: (event: WsEvent) => void;
1335
+ };
1336
+ declare function createDmThreadsStore(): DmThreadsStore;
1337
+
1338
+ type ChatContextType = 'lobby' | 'game' | 'dm' | 'global';
1339
+ interface ChatContext {
1340
+ type: ChatContextType;
1210
1341
  id: string;
1211
- userId?: string;
1212
- username?: string;
1213
- message: string;
1214
- }
1215
- interface ChatReaction {
1216
- emoji: string;
1217
- userId: string;
1218
- username?: string;
1219
- createdAt: string;
1220
- }
1221
- interface ChatReadBy {
1222
- userId: string;
1223
- readAt: string;
1224
1342
  }
1225
- interface ChatMessage {
1226
- id: string;
1227
- lobbyId: string;
1228
- userId?: string;
1229
- username?: string;
1230
- avatarUrl?: string;
1343
+ interface SendMessageRequest {
1231
1344
  message: string;
1232
- type: ChatMessageType;
1233
- systemType?: SystemMessageType;
1234
- metadata?: Record<string, any>;
1235
1345
  replyTo?: ChatMessageReply;
1236
- reactions?: ChatReaction[];
1237
- readBy?: ChatReadBy[];
1238
- createdAt: string;
1346
+ gifUrl?: string;
1239
1347
  }
1240
-
1241
- declare class Lobbies {
1348
+ interface DmThread {
1349
+ dmKey: string;
1350
+ otherUser: PublicUser;
1351
+ lastMessage: string | null;
1352
+ lastMessageAt: string | null;
1353
+ lastMessageSenderId: string | null;
1354
+ lastMessageSenderUsername: string | null;
1355
+ unreadCount: number;
1356
+ }
1357
+ declare class Chat {
1242
1358
  private http;
1243
1359
  private logger?;
1244
- constructor(http: IHttpClient, logger?: ILogger | undefined);
1245
- createLobby(gameType: string, betAmount?: MoneyMinor): Promise<Lobby>;
1246
- getLobby(lobbyId: string): Promise<Lobby>;
1247
- inviteFriend(lobbyId: string, friendId: string): Promise<{
1248
- message: string;
1249
- }>;
1250
- acceptInvite(lobbyId: string): Promise<Lobby>;
1251
- joinLobby(lobbyId: string): Promise<Lobby>;
1252
- removePlayer(lobbyId: string, userId: string): Promise<{
1253
- message: string;
1254
- }>;
1255
- kickPlayer(lobbyId: string, userId: string): Promise<{
1256
- message: string;
1257
- }>;
1258
- leaveLobby(lobbyId: string): Promise<{
1259
- message: string;
1260
- }>;
1261
- joinQueue(lobbyId: string): Promise<Lobby>;
1262
- cancelQueue(lobbyId: string): Promise<Lobby>;
1263
- updateBetAmount(lobbyId: string, betAmount: MoneyMinor): Promise<Lobby>;
1264
- playSound(lobbyId: string, sound: string): Promise<{
1265
- success: boolean;
1360
+ private retryOptions;
1361
+ private dmThreadsStore?;
1362
+ constructor(http: IHttpClient, logger?: any | undefined, retryOptions?: RetryOptions);
1363
+ setDmThreadsStore(store: DmThreadsStore): void;
1364
+ private encodeContextId;
1365
+ /**
1366
+ * Send a chat message with automatic retry on transient failures
1367
+ *
1368
+ * @param clientMessageId - Optional client-generated ID for optimistic UI.
1369
+ * Echoed back in response metadata for deduplication.
1370
+ */
1371
+ sendMessage(context: ChatContext, message: string, replyTo?: ChatMessageReply, gifUrl?: string, clientMessageId?: string): Promise<ChatMessage>;
1372
+ /** Response from paginated chat history */
1373
+ getChatHistory(context: ChatContext, limit?: number, cursor?: string): Promise<ChatMessage[]>;
1374
+ /**
1375
+ * Get chat history with pagination support.
1376
+ * Returns messages and a cursor for loading older messages.
1377
+ * For global context, uses the public endpoint so it works without auth.
1378
+ */
1379
+ getChatHistoryPaginated(context: ChatContext, limit?: number, cursor?: string): Promise<{
1380
+ messages: ChatMessage[];
1381
+ nextCursor: string | null;
1266
1382
  }>;
1267
- getActiveLobbies(): Promise<Lobby[]>;
1268
- getQueueStats(): Promise<QueueStats>;
1269
- deleteLobby(lobbyId: string): Promise<{
1270
- message: string;
1383
+ /**
1384
+ * Add a reaction to a message
1385
+ */
1386
+ addReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1387
+ /**
1388
+ * Remove a reaction from a message
1389
+ */
1390
+ removeReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1391
+ /**
1392
+ * Mark a message as read
1393
+ */
1394
+ markAsRead(context: ChatContext, messageId: string): Promise<ChatMessage>;
1395
+ listDmThreads(): Promise<DmThread[]>;
1396
+ getDmThread(dmKey: string): Promise<DmThread>;
1397
+ /**
1398
+ * Mark all messages in a DM thread as read
1399
+ */
1400
+ markDmThreadAsRead(dmKey: string): Promise<{
1401
+ markedCount: number;
1271
1402
  }>;
1272
1403
  /**
1273
- * Play again: Create a new lobby and prepare deposit in one flow.
1274
- * Returns the lobby and unsigned transaction that needs to be signed.
1275
- * @param gameType - The game type to play again
1276
- * @param betAmount - The bet amount (same as previous game)
1277
- * @param escrow - The escrow service instance (from sdk.escrow)
1404
+ * Accept a global chat challenge. Returns the lobby (and gameId if started).
1278
1405
  */
1279
- playAgain(gameType: string, betAmount: MoneyMinor, escrow: {
1280
- prepareAndStartDeposit: (id: string) => Promise<{
1281
- transaction: string;
1282
- message: string;
1283
- }>;
1284
- }): Promise<{
1285
- lobby: Lobby;
1286
- unsignedTransaction: string;
1406
+ acceptGlobalChallenge(challengeId: string): Promise<{
1407
+ lobbyId: string;
1408
+ gameId?: string;
1409
+ status: string;
1287
1410
  }>;
1411
+ /**
1412
+ * Broadcast a tip message to global chat (call after the user has signed and submitted the transfer).
1413
+ */
1414
+ broadcastGlobalTip(recipientUserId: string, amount: number): Promise<ChatMessage>;
1288
1415
  }
1289
1416
 
1417
+ type GameStoreState = {
1418
+ gamesById: Record<string, Game>;
1419
+ /** Real-time spectator counts by userId, updated via spectator:count:updated WS events. */
1420
+ spectatorCounts: Record<string, number>;
1421
+ };
1422
+ type GameStore = {
1423
+ store: SdkStore<GameStoreState>;
1424
+ setBaseState: (games: Game[]) => void;
1425
+ applyWsEvent: (event: WsEvent) => void;
1426
+ joinGame: (gameId: string) => () => void;
1427
+ /** Join the spectate channel for a user. Returns a leave function. */
1428
+ joinSpectateChannel: (spectatedUserId: string) => () => void;
1429
+ /** Get a snapshot of the spectator count for a user (from the store). */
1430
+ getSpectatorCount: (userId: string) => number;
1431
+ };
1432
+ declare function createGameStore(transport: WsTransport): GameStore;
1433
+
1434
+ type GameActionsStoreState = {
1435
+ statesByGameId: Record<string, GameStateResponse>;
1436
+ };
1437
+ type GameActionsStore = {
1438
+ store: SdkStore<GameActionsStoreState>;
1439
+ setBaseState: (gameId: string, state: GameStateResponse) => void;
1440
+ clearState: (gameId: string) => void;
1441
+ applyWsEvent: (event: WsEvent) => void;
1442
+ joinGame: (gameId: string) => () => void;
1443
+ };
1444
+ declare function createGameActionsStore(transport: WsTransport): GameActionsStore;
1445
+
1290
1446
  interface GameType {
1291
1447
  id: string;
1292
1448
  name: string;
@@ -1392,7 +1548,11 @@ declare class Games {
1392
1548
  private http;
1393
1549
  private wallet;
1394
1550
  private logger?;
1551
+ private gameStore?;
1552
+ private gameActionsStore?;
1395
1553
  constructor(http: IHttpClient, wallet: Wallet, logger?: ILogger | undefined);
1554
+ setGameStore(store: GameStore): void;
1555
+ setGameActionsStore(store: GameActionsStore): void;
1396
1556
  getAvailableGames(): Promise<GameType[]>;
1397
1557
  /**
1398
1558
  * Get real-time metrics for all games.
@@ -1455,8 +1615,16 @@ declare class Games {
1455
1615
  signature: string;
1456
1616
  status: string;
1457
1617
  }>;
1618
+ /**
1619
+ * Confirm a donation that was already sent by the client (signAndSendTransaction path).
1620
+ */
1621
+ confirmGameDonationSignature(gameId: string, amountMinor: number, signature: string): Promise<{
1622
+ signature: string;
1623
+ status: string;
1624
+ }>;
1458
1625
  /**
1459
1626
  * One-call donation flow: prepare -> sign -> submit.
1627
+ * Automatically uses the right signing path (embedded vs injected wallet).
1460
1628
  */
1461
1629
  sendDonation(gameId: string, amountMinor: number): Promise<DonateToGameResponse>;
1462
1630
  /**
@@ -1466,249 +1634,6 @@ declare class Games {
1466
1634
  notifyRematchLobbyCreated(gameId: string, lobbyId: string): Promise<void>;
1467
1635
  }
1468
1636
 
1469
- /** A player currently in an active game; used for "Live now" and "Who to watch" UI. */
1470
- interface LivePlayer {
1471
- userId: string;
1472
- username: string;
1473
- avatar?: string;
1474
- gameId: string;
1475
- gameType: string;
1476
- spectatorCount: number;
1477
- }
1478
- /** Paginated response for live players (newest first, sample of games per page). */
1479
- interface LivePlayersPage {
1480
- items: LivePlayer[];
1481
- nextCursor: string | null;
1482
- }
1483
- /**
1484
- * SDK class for spectate discovery — finding who to watch.
1485
- *
1486
- * @example
1487
- * ```ts
1488
- * const page = await sdk.spectate.getLivePlayers({ limit: 10 });
1489
- * console.log(page.items); // LivePlayer[]
1490
- * ```
1491
- */
1492
- declare class Spectate {
1493
- private http;
1494
- private logger?;
1495
- constructor(http: IHttpClient, logger?: ILogger | undefined);
1496
- /**
1497
- * Get list of live players (one per unique player), sampled from newest games, paginated.
1498
- * Use for "Live now" and "Who to watch" UI; link to /spectate/:username.
1499
- * @param options.limit - Number of games to consider per page (1–20, default 10).
1500
- * @param options.cursor - Opaque cursor from previous page for next page.
1501
- */
1502
- getLivePlayers(options?: {
1503
- limit?: number;
1504
- cursor?: string;
1505
- }): Promise<LivePlayersPage>;
1506
- }
1507
-
1508
- /**
1509
- * Retry configuration options
1510
- */
1511
- interface RetryOptions {
1512
- /** Maximum number of retry attempts (default: 3) */
1513
- maxAttempts?: number;
1514
- /** Base delay in milliseconds (default: 1000) */
1515
- baseDelayMs?: number;
1516
- /** Maximum delay in milliseconds (default: 10000) */
1517
- maxDelayMs?: number;
1518
- /** Multiplier for exponential backoff (default: 2) */
1519
- backoffMultiplier?: number;
1520
- /** Function to determine if error is retryable (default: network/5xx errors) */
1521
- isRetryable?: (error: unknown) => boolean;
1522
- /** Callback for each retry attempt */
1523
- onRetry?: (attempt: number, error: unknown, delayMs: number) => void;
1524
- }
1525
- /**
1526
- * Default function to determine if an error is retryable.
1527
- * Retries on network errors and 5xx server errors.
1528
- */
1529
- declare function isRetryableError(error: unknown): boolean;
1530
- /**
1531
- * Execute an async function with exponential backoff retry.
1532
- *
1533
- * @param fn - Async function to execute
1534
- * @param options - Retry configuration
1535
- * @returns Promise resolving to the function result
1536
- * @throws Last error if all retries exhausted
1537
- *
1538
- * @example
1539
- * ```typescript
1540
- * const result = await withRetry(
1541
- * () => fetch('/api/data'),
1542
- * { maxAttempts: 3, baseDelayMs: 500 }
1543
- * );
1544
- * ```
1545
- */
1546
- declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1547
-
1548
- type ChatContextType = 'lobby' | 'game' | 'dm' | 'global';
1549
- interface ChatContext {
1550
- type: ChatContextType;
1551
- id: string;
1552
- }
1553
- interface SendMessageRequest {
1554
- message: string;
1555
- replyTo?: ChatMessageReply;
1556
- gifUrl?: string;
1557
- }
1558
- interface DmThread {
1559
- dmKey: string;
1560
- otherUser: PublicUser;
1561
- lastMessage: string | null;
1562
- lastMessageAt: string | null;
1563
- lastMessageSenderId: string | null;
1564
- lastMessageSenderUsername: string | null;
1565
- unreadCount: number;
1566
- }
1567
- declare class Chat {
1568
- private http;
1569
- private logger?;
1570
- private retryOptions;
1571
- constructor(http: IHttpClient, logger?: any | undefined, retryOptions?: RetryOptions);
1572
- private encodeContextId;
1573
- /**
1574
- * Send a chat message with automatic retry on transient failures
1575
- *
1576
- * @param clientMessageId - Optional client-generated ID for optimistic UI.
1577
- * Echoed back in response metadata for deduplication.
1578
- */
1579
- sendMessage(context: ChatContext, message: string, replyTo?: ChatMessageReply, gifUrl?: string, clientMessageId?: string): Promise<ChatMessage>;
1580
- /** Response from paginated chat history */
1581
- getChatHistory(context: ChatContext, limit?: number, cursor?: string): Promise<ChatMessage[]>;
1582
- /**
1583
- * Get chat history with pagination support.
1584
- * Returns messages and a cursor for loading older messages.
1585
- * For global context, uses the public endpoint so it works without auth.
1586
- */
1587
- getChatHistoryPaginated(context: ChatContext, limit?: number, cursor?: string): Promise<{
1588
- messages: ChatMessage[];
1589
- nextCursor: string | null;
1590
- }>;
1591
- /**
1592
- * Add a reaction to a message
1593
- */
1594
- addReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1595
- /**
1596
- * Remove a reaction from a message
1597
- */
1598
- removeReaction(context: ChatContext, messageId: string, emoji: string): Promise<ChatMessage>;
1599
- /**
1600
- * Mark a message as read
1601
- */
1602
- markAsRead(context: ChatContext, messageId: string): Promise<ChatMessage>;
1603
- listDmThreads(): Promise<DmThread[]>;
1604
- getDmThread(dmKey: string): Promise<DmThread>;
1605
- /**
1606
- * Mark all messages in a DM thread as read
1607
- */
1608
- markDmThreadAsRead(dmKey: string): Promise<{
1609
- markedCount: number;
1610
- }>;
1611
- /**
1612
- * Accept a global chat challenge. Returns the lobby (and gameId if started).
1613
- */
1614
- acceptGlobalChallenge(challengeId: string): Promise<{
1615
- lobbyId: string;
1616
- gameId?: string;
1617
- status: string;
1618
- }>;
1619
- /**
1620
- * Broadcast a tip message to global chat (call after the user has signed and submitted the transfer).
1621
- */
1622
- broadcastGlobalTip(recipientUserId: string, amount: number): Promise<ChatMessage>;
1623
- }
1624
-
1625
- interface CreateChallengeRequest {
1626
- gameType: string;
1627
- amount: number;
1628
- targetUserId?: string;
1629
- targetUsername?: string;
1630
- /** When set, post challenge system message to this DM thread (format: "userId1:userId2" sorted). */
1631
- dmKey?: string;
1632
- }
1633
- interface CreateChallengeResponse {
1634
- challengeId: string;
1635
- challengerId: string;
1636
- targetUserId: string;
1637
- gameType: string;
1638
- amountMinor: number;
1639
- challengerUsername?: string;
1640
- }
1641
- interface AcceptChallengeResponse {
1642
- lobbyId: string;
1643
- gameId?: string;
1644
- status: string;
1645
- }
1646
- declare class Challenges {
1647
- private http;
1648
- private logger?;
1649
- constructor(http: IHttpClient, logger?: any | undefined);
1650
- /**
1651
- * Create a challenge (any user can challenge any other user by id or username).
1652
- */
1653
- create(dto: CreateChallengeRequest): Promise<CreateChallengeResponse>;
1654
- /**
1655
- * Accept a challenge. Only the challenged user can accept. Creates a lobby with the challenge amount and adds both users.
1656
- */
1657
- accept(challengeId: string): Promise<AcceptChallengeResponse>;
1658
- /**
1659
- * Decline a challenge. Only the challenged user can decline. Optionally post a "declined" message to the DM thread.
1660
- */
1661
- decline(challengeId: string, dmKey?: string): Promise<{
1662
- message?: string;
1663
- }>;
1664
- }
1665
-
1666
- interface PrepareTipRequest {
1667
- recipientUsername: string;
1668
- amount: number;
1669
- }
1670
- interface PrepareTipResponse {
1671
- transaction: string;
1672
- fee: number;
1673
- totalAmount: number;
1674
- recipientAddress: string;
1675
- recipientUserId: string;
1676
- recipientUsername: string;
1677
- amount: number;
1678
- }
1679
- interface BroadcastTipRequest {
1680
- recipientUserId: string;
1681
- amount: number;
1682
- }
1683
- interface SendTipResponse extends SubmitTransferResponse {
1684
- recipientAddress: string;
1685
- recipientUserId: string;
1686
- recipientUsername: string;
1687
- amount: number;
1688
- fee: number;
1689
- totalAmount: number;
1690
- message: ChatMessage;
1691
- }
1692
- /**
1693
- * Tips are a shorthand for wallet send + global tip broadcast.
1694
- */
1695
- declare class Tips {
1696
- private http;
1697
- private wallet;
1698
- private chat;
1699
- private logger?;
1700
- constructor(http: IHttpClient, wallet: Wallet, chat: Chat, logger?: any | undefined);
1701
- prepare(dto: PrepareTipRequest): Promise<PrepareTipResponse>;
1702
- /**
1703
- * Broadcast a tip message to global chat (call after the transfer has been submitted).
1704
- */
1705
- broadcast(dto: BroadcastTipRequest): Promise<ChatMessage>;
1706
- /**
1707
- * One-call tip flow: prepare -> sign -> submit transfer -> broadcast tip message.
1708
- */
1709
- send(recipientUsername: string, amount: number): Promise<SendTipResponse>;
1710
- }
1711
-
1712
1637
  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:deposit:updated' | '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';
1713
1638
  type GameTurnPayload = {
1714
1639
  turn: number;
@@ -1815,7 +1740,7 @@ type MarketResolvedPayload = {
1815
1740
  type LobbyDepositUpdatedPayload = {
1816
1741
  lobbyId: string;
1817
1742
  userId: string;
1818
- status: string;
1743
+ status: 'confirmed' | 'failed' | 'refunded' | 'refund_failed';
1819
1744
  allConfirmed: boolean;
1820
1745
  };
1821
1746
  type WsEvent = {
@@ -2017,16 +1942,278 @@ type WsEvent = {
2017
1942
  payload: unknown;
2018
1943
  };
2019
1944
 
2020
- type EqualityFn<T> = (a: T, b: T) => boolean;
2021
- interface SdkStore<S> {
2022
- getSnapshot(): S;
2023
- getState(): S;
2024
- setState(next: S): void;
2025
- updateState(updater: (prev: S) => S): void;
2026
- subscribe(listener: () => void): () => void;
2027
- subscribeSelector<T>(selector: (state: S) => T, listener: () => void, isEqual?: EqualityFn<T>): () => void;
1945
+ type LobbyMatchedEvent = {
1946
+ gameId: string;
1947
+ gameType: string;
1948
+ matchedLobbies: Lobby[];
1949
+ };
1950
+ type LobbyStoreState = {
1951
+ lobbiesById: Record<string, Lobby>;
1952
+ matchedEvent: LobbyMatchedEvent | null;
1953
+ typingByLobbyId: Record<string, string[]>;
1954
+ depositStatusByLobbyId: Record<string, LobbyDepositUpdatedPayload>;
1955
+ };
1956
+ type LobbyStore = {
1957
+ store: SdkStore<LobbyStoreState>;
1958
+ setBaseState: (lobbies: Lobby[]) => void;
1959
+ applyWsEvent: (event: WsEvent) => void;
1960
+ joinLobby: (lobbyId: string) => () => void;
1961
+ subscribeMatched: (callback: (event: LobbyMatchedEvent) => void) => () => void;
1962
+ subscribeDepositUpdate: (lobbyId: string, callback: (data: LobbyDepositUpdatedPayload) => void) => () => void;
1963
+ };
1964
+ declare function createLobbyStore(transport: WsTransport): LobbyStore;
1965
+
1966
+ interface BetOption {
1967
+ amount: MoneyMinor;
1968
+ playersOnline: number;
1969
+ estimatedTime: string;
1970
+ }
1971
+ interface LobbyPlayer {
1972
+ userId: string;
1973
+ username?: string;
1974
+ avatar?: string;
1975
+ joinedAt: string;
1976
+ connected?: boolean;
1977
+ /** USDC balance in minor units (cached, short TTL). Shown in lobby and used to gate Start Game. */
1978
+ usdcBalance?: number;
1979
+ }
1980
+ interface Lobby {
1981
+ id: string;
1982
+ gameType: string;
1983
+ gameName: string;
1984
+ status: 'waiting' | 'preparing' | 'queued' | 'active';
1985
+ creatorId: string;
1986
+ maxPlayers: number;
1987
+ betAmount?: MoneyMinor;
1988
+ betOptions?: BetOption[];
1989
+ gameId?: string;
1990
+ createdAt: string;
1991
+ updatedAt: string;
1992
+ players: LobbyPlayer[];
1993
+ }
1994
+ interface CreateLobbyRequest {
1995
+ gameType: string;
1996
+ }
1997
+ interface InviteFriendRequest {
1998
+ friendId: string;
1999
+ }
2000
+ interface QueueStats {
2001
+ totalPlayersInQueue: number;
2002
+ queueSizes: Record<string, number>;
2003
+ totalQueuedLobbies: number;
2004
+ }
2005
+ type ChatMessageType = 'user' | 'system';
2006
+ type SystemMessageType = 'player_joined' | 'player_left' | 'bet_changed' | 'call_joined' | 'call_left' | 'global_help' | 'global_challenge' | 'global_tip' | 'spectator_donation' | 'challenge_accepted' | 'challenge_declined';
2007
+ interface ChatMessageReply {
2008
+ id: string;
2009
+ userId?: string;
2010
+ username?: string;
2011
+ message: string;
2012
+ }
2013
+ interface ChatReaction {
2014
+ emoji: string;
2015
+ userId: string;
2016
+ username?: string;
2017
+ createdAt: string;
2018
+ }
2019
+ interface ChatReadBy {
2020
+ userId: string;
2021
+ readAt: string;
2022
+ }
2023
+ interface ChatMessage {
2024
+ id: string;
2025
+ lobbyId: string;
2026
+ userId?: string;
2027
+ username?: string;
2028
+ avatarUrl?: string;
2029
+ message: string;
2030
+ type: ChatMessageType;
2031
+ systemType?: SystemMessageType;
2032
+ metadata?: Record<string, any>;
2033
+ replyTo?: ChatMessageReply;
2034
+ reactions?: ChatReaction[];
2035
+ readBy?: ChatReadBy[];
2036
+ createdAt: string;
2037
+ }
2038
+
2039
+ declare class Lobbies {
2040
+ private http;
2041
+ private logger?;
2042
+ private lobbyStore?;
2043
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2044
+ /** Called by SDK after the store is created so mutations can update state directly. */
2045
+ setLobbyStore(store: LobbyStore): void;
2046
+ createLobby(gameType: string, betAmount?: MoneyMinor): Promise<Lobby>;
2047
+ getLobby(lobbyId: string): Promise<Lobby>;
2048
+ inviteFriend(lobbyId: string, friendId: string): Promise<{
2049
+ message: string;
2050
+ }>;
2051
+ acceptInvite(lobbyId: string): Promise<Lobby>;
2052
+ joinLobby(lobbyId: string): Promise<Lobby>;
2053
+ removePlayer(lobbyId: string, userId: string): Promise<{
2054
+ message: string;
2055
+ }>;
2056
+ kickPlayer(lobbyId: string, userId: string): Promise<{
2057
+ message: string;
2058
+ }>;
2059
+ leaveLobby(lobbyId: string): Promise<{
2060
+ message: string;
2061
+ }>;
2062
+ joinQueue(lobbyId: string): Promise<Lobby>;
2063
+ cancelQueue(lobbyId: string): Promise<Lobby>;
2064
+ updateBetAmount(lobbyId: string, betAmount: MoneyMinor): Promise<Lobby>;
2065
+ playSound(lobbyId: string, sound: string): Promise<{
2066
+ success: boolean;
2067
+ }>;
2068
+ getActiveLobbies(): Promise<Lobby[]>;
2069
+ getQueueStats(): Promise<QueueStats>;
2070
+ deleteLobby(lobbyId: string): Promise<{
2071
+ message: string;
2072
+ }>;
2073
+ /**
2074
+ * Play again: Create a new lobby and prepare deposit in one flow.
2075
+ * Returns the lobby and unsigned transaction that needs to be signed.
2076
+ * @param gameType - The game type to play again
2077
+ * @param betAmount - The bet amount (same as previous game)
2078
+ * @param escrow - The escrow service instance (from sdk.escrow)
2079
+ */
2080
+ playAgain(gameType: string, betAmount: MoneyMinor, escrow: {
2081
+ prepareAndStartDeposit: (id: string) => Promise<{
2082
+ transaction: string;
2083
+ message: string;
2084
+ }>;
2085
+ }): Promise<{
2086
+ lobby: Lobby;
2087
+ unsignedTransaction: string;
2088
+ }>;
2089
+ }
2090
+
2091
+ /** A player currently in an active game; used for "Live now" and "Who to watch" UI. */
2092
+ interface LivePlayer {
2093
+ userId: string;
2094
+ username: string;
2095
+ avatar?: string;
2096
+ gameId: string;
2097
+ gameType: string;
2098
+ spectatorCount: number;
2099
+ }
2100
+ /** Paginated response for live players (newest first, sample of games per page). */
2101
+ interface LivePlayersPage {
2102
+ items: LivePlayer[];
2103
+ nextCursor: string | null;
2104
+ }
2105
+ /**
2106
+ * SDK class for spectate discovery — finding who to watch.
2107
+ *
2108
+ * @example
2109
+ * ```ts
2110
+ * const page = await sdk.spectate.getLivePlayers({ limit: 10 });
2111
+ * console.log(page.items); // LivePlayer[]
2112
+ * ```
2113
+ */
2114
+ declare class Spectate {
2115
+ private http;
2116
+ private logger?;
2117
+ constructor(http: IHttpClient, logger?: ILogger | undefined);
2118
+ /**
2119
+ * Get list of live players (one per unique player), sampled from newest games, paginated.
2120
+ * Use for "Live now" and "Who to watch" UI; link to /spectate/:username.
2121
+ * @param options.limit - Number of games to consider per page (1–20, default 10).
2122
+ * @param options.cursor - Opaque cursor from previous page for next page.
2123
+ */
2124
+ getLivePlayers(options?: {
2125
+ limit?: number;
2126
+ cursor?: string;
2127
+ }): Promise<LivePlayersPage>;
2128
+ }
2129
+
2130
+ interface CreateChallengeRequest {
2131
+ gameType: string;
2132
+ amount: number;
2133
+ targetUserId?: string;
2134
+ targetUsername?: string;
2135
+ /** When set, post challenge system message to this DM thread (format: "userId1:userId2" sorted). */
2136
+ dmKey?: string;
2137
+ }
2138
+ interface CreateChallengeResponse {
2139
+ challengeId: string;
2140
+ challengerId: string;
2141
+ targetUserId: string;
2142
+ gameType: string;
2143
+ amountMinor: number;
2144
+ challengerUsername?: string;
2145
+ }
2146
+ interface AcceptChallengeResponse {
2147
+ lobbyId: string;
2148
+ gameId?: string;
2149
+ status: string;
2150
+ }
2151
+ declare class Challenges {
2152
+ private http;
2153
+ private logger?;
2154
+ constructor(http: IHttpClient, logger?: any | undefined);
2155
+ /**
2156
+ * Create a challenge (any user can challenge any other user by id or username).
2157
+ */
2158
+ create(dto: CreateChallengeRequest): Promise<CreateChallengeResponse>;
2159
+ /**
2160
+ * Accept a challenge. Only the challenged user can accept. Creates a lobby with the challenge amount and adds both users.
2161
+ */
2162
+ accept(challengeId: string): Promise<AcceptChallengeResponse>;
2163
+ /**
2164
+ * Decline a challenge. Only the challenged user can decline. Optionally post a "declined" message to the DM thread.
2165
+ */
2166
+ decline(challengeId: string, dmKey?: string): Promise<{
2167
+ message?: string;
2168
+ }>;
2169
+ }
2170
+
2171
+ interface PrepareTipRequest {
2172
+ recipientUsername: string;
2173
+ amount: number;
2174
+ supportsPresign?: boolean;
2175
+ }
2176
+ interface PrepareTipResponse {
2177
+ transaction: string;
2178
+ fee: number;
2179
+ totalAmount: number;
2180
+ recipientAddress: string;
2181
+ recipientUserId: string;
2182
+ recipientUsername: string;
2183
+ amount: number;
2184
+ }
2185
+ interface BroadcastTipRequest {
2186
+ recipientUserId: string;
2187
+ amount: number;
2188
+ }
2189
+ interface SendTipResponse extends SubmitTransferResponse {
2190
+ recipientAddress: string;
2191
+ recipientUserId: string;
2192
+ recipientUsername: string;
2193
+ amount: number;
2194
+ fee: number;
2195
+ totalAmount: number;
2196
+ message: ChatMessage;
2197
+ }
2198
+ /**
2199
+ * Tips are a shorthand for wallet send + global tip broadcast.
2200
+ */
2201
+ declare class Tips {
2202
+ private http;
2203
+ private wallet;
2204
+ private chat;
2205
+ private logger?;
2206
+ constructor(http: IHttpClient, wallet: Wallet, chat: Chat, logger?: any | undefined);
2207
+ prepare(dto: PrepareTipRequest): Promise<PrepareTipResponse>;
2208
+ /**
2209
+ * Broadcast a tip message to global chat (call after the transfer has been submitted).
2210
+ */
2211
+ broadcast(dto: BroadcastTipRequest): Promise<ChatMessage>;
2212
+ /**
2213
+ * One-call tip flow: prepare -> sign -> submit transfer -> broadcast tip message.
2214
+ */
2215
+ send(recipientUsername: string, amount: number): Promise<SendTipResponse>;
2028
2216
  }
2029
- declare function createSdkStore<S>(initial: S): SdkStore<S>;
2030
2217
 
2031
2218
  type NotificationEvent = {
2032
2219
  title: string;
@@ -2050,6 +2237,9 @@ type NotificationsStore = {
2050
2237
  applyWsEvent: (event: WsEvent) => void;
2051
2238
  setListFromApi: (res: PaginatedNotificationsResponse) => void;
2052
2239
  clear: () => void;
2240
+ markAsRead: (id: string) => void;
2241
+ markAllAsRead: () => void;
2242
+ dismiss: (id: string) => void;
2053
2243
  };
2054
2244
  declare function createNotificationsStore(): NotificationsStore;
2055
2245
 
@@ -2159,7 +2349,15 @@ declare class Escrow {
2159
2349
  * initializes depositStatus, and prepares the unsigned transaction in one call.
2160
2350
  * Eliminates one HTTP round-trip vs startDeposits() + prepareDepositTransaction().
2161
2351
  */
2162
- prepareAndStartDeposit(lobbyId: string): Promise<PrepareDepositResponse>;
2352
+ prepareAndStartDeposit(lobbyId: string, supportsPresign?: boolean): Promise<PrepareDepositResponse>;
2353
+ /**
2354
+ * Sign and submit a prepared (unsigned) deposit transaction using the
2355
+ * configured signer. Automatically picks the right path:
2356
+ * - Embedded wallet: signAndSendTransaction → confirmDepositSignature
2357
+ * - Injected wallet: signTransaction → submitDeposit
2358
+ * Returns the on-chain signature.
2359
+ */
2360
+ signAndSubmitPreparedDeposit(lobbyId: string, unsignedTxBase64: string): Promise<string>;
2163
2361
  /**
2164
2362
  * Submit a signed deposit transaction
2165
2363
  * The transaction will be submitted to the Solana network and confirmed
@@ -2184,8 +2382,13 @@ declare class Escrow {
2184
2382
  */
2185
2383
  depositForLobby(lobbyId: string): Promise<DepositForLobbyResponse>;
2186
2384
  /**
2187
- * Zero-polling deposit variant using server-side awaitConfirmation.
2188
- * 2 HTTP calls total, 0 client-side polling. Ideal for agents.
2385
+ * Deposit for a lobby and wait until the calling user's own deposit is confirmed.
2386
+ * Ideal for agents: returns as soon as your deposit is on-chain without waiting
2387
+ * for the other player. The server auto-joins the queue when all players deposit.
2388
+ *
2389
+ * Confirmation is handled asynchronously by the transaction queue processor.
2390
+ * This method polls the deposit status endpoint until the signature appears as
2391
+ * confirmed (up to 60 seconds).
2189
2392
  *
2190
2393
  * Automatically uses signAndSendTransaction or signTransaction based on signer capability.
2191
2394
  */
@@ -2500,7 +2703,8 @@ interface AdminMarketDetail {
2500
2703
  declare class Markets {
2501
2704
  private http;
2502
2705
  private logger?;
2503
- constructor(http: IHttpClient, logger?: ILogger | undefined);
2706
+ private wallet?;
2707
+ constructor(http: IHttpClient, logger?: ILogger | undefined, wallet?: Wallet | undefined);
2504
2708
  /**
2505
2709
  * Get the prediction market state for a game.
2506
2710
  * Returns prices, volume, collateral, and resolution status.
@@ -2529,6 +2733,15 @@ declare class Markets {
2529
2733
  * @param amountMinor - Amount to spend in USDC minor units
2530
2734
  */
2531
2735
  submitBuyOrder(gameId: string, signedTransaction: string, outcomeId: string, amountMinor: number): Promise<MarketBuyResult>;
2736
+ /**
2737
+ * Confirm a buy order that was already broadcast by the client (signAndSendTransaction path).
2738
+ */
2739
+ confirmBuyOrderSignature(gameId: string, depositSignature: string, outcomeId: string, amountMinor: number): Promise<MarketBuyResult>;
2740
+ /**
2741
+ * One-call buy order: prepare → sign → submit, automatically choosing
2742
+ * the right signing path (embedded vs injected wallet).
2743
+ */
2744
+ buy(gameId: string, outcomeId: string, amountMinor: number): Promise<MarketBuyResult>;
2532
2745
  /**
2533
2746
  * Sell shares back to the AMM pool.
2534
2747
  * @param gameId - The game ID
@@ -2562,56 +2775,6 @@ declare class Markets {
2562
2775
  }>;
2563
2776
  }
2564
2777
 
2565
- type LobbyMatchedEvent = {
2566
- gameId: string;
2567
- gameType: string;
2568
- matchedLobbies: Lobby[];
2569
- };
2570
- type LobbyStoreState = {
2571
- lobbiesById: Record<string, Lobby>;
2572
- matchedEvent: LobbyMatchedEvent | null;
2573
- typingByLobbyId: Record<string, string[]>;
2574
- depositStatusByLobbyId: Record<string, LobbyDepositUpdatedPayload>;
2575
- };
2576
- type LobbyStore = {
2577
- store: SdkStore<LobbyStoreState>;
2578
- setBaseState: (lobbies: Lobby[]) => void;
2579
- applyWsEvent: (event: WsEvent) => void;
2580
- joinLobby: (lobbyId: string) => () => void;
2581
- subscribeMatched: (callback: (event: LobbyMatchedEvent) => void) => () => void;
2582
- subscribeDepositUpdate: (lobbyId: string, callback: (data: LobbyDepositUpdatedPayload) => void) => () => void;
2583
- };
2584
- declare function createLobbyStore(transport: WsTransport): LobbyStore;
2585
-
2586
- type GameStoreState = {
2587
- gamesById: Record<string, Game>;
2588
- /** Real-time spectator counts by userId, updated via spectator:count:updated WS events. */
2589
- spectatorCounts: Record<string, number>;
2590
- };
2591
- type GameStore = {
2592
- store: SdkStore<GameStoreState>;
2593
- setBaseState: (games: Game[]) => void;
2594
- applyWsEvent: (event: WsEvent) => void;
2595
- joinGame: (gameId: string) => () => void;
2596
- /** Join the spectate channel for a user. Returns a leave function. */
2597
- joinSpectateChannel: (spectatedUserId: string) => () => void;
2598
- /** Get a snapshot of the spectator count for a user (from the store). */
2599
- getSpectatorCount: (userId: string) => number;
2600
- };
2601
- declare function createGameStore(transport: WsTransport): GameStore;
2602
-
2603
- type GameActionsStoreState = {
2604
- statesByGameId: Record<string, GameStateResponse>;
2605
- };
2606
- type GameActionsStore = {
2607
- store: SdkStore<GameActionsStoreState>;
2608
- setBaseState: (gameId: string, state: GameStateResponse) => void;
2609
- clearState: (gameId: string) => void;
2610
- applyWsEvent: (event: WsEvent) => void;
2611
- joinGame: (gameId: string) => () => void;
2612
- };
2613
- declare function createGameActionsStore(transport: WsTransport): GameActionsStore;
2614
-
2615
2778
  interface TypingUser {
2616
2779
  userId: string;
2617
2780
  username?: string;
@@ -2633,22 +2796,6 @@ type ChatStore = {
2633
2796
  };
2634
2797
  declare function createChatStore(transport: WsTransport): ChatStore;
2635
2798
 
2636
- type DmThreadsStoreState = {
2637
- threads: DmThread[];
2638
- loading: boolean;
2639
- error: string | null;
2640
- needsRefresh: boolean;
2641
- };
2642
- type DmThreadsStore = {
2643
- store: SdkStore<DmThreadsStoreState>;
2644
- setBaseState: (threads: DmThread[]) => void;
2645
- setLoading: (loading: boolean) => void;
2646
- setError: (error: string | null) => void;
2647
- setCurrentUserId: (userId: string | null) => void;
2648
- applyWsEvent: (event: WsEvent) => void;
2649
- };
2650
- declare function createDmThreadsStore(): DmThreadsStore;
2651
-
2652
2799
  type FriendshipStatus = 'none' | 'incoming' | 'outgoing' | 'friends';
2653
2800
  type FriendsStoreState = {
2654
2801
  /** Optimistic overrides keyed by userId. Only set when status differs from API (e.g. 'outgoing' after send, cleared when API data arrives). */
@@ -2711,6 +2858,7 @@ declare class SDK {
2711
2858
  notificationsStore: NotificationsStore;
2712
2859
  friendsStore: FriendsStore;
2713
2860
  events: WsEventBus;
2861
+ analytics: IAnalyticsClient;
2714
2862
  private wsRouter;
2715
2863
  constructor(config: SDKConfig);
2716
2864
  /**
@@ -2720,6 +2868,18 @@ declare class SDK {
2720
2868
  * to be connected to the app via WebSocket.
2721
2869
  */
2722
2870
  ensureWebSocketConnected(timeoutMs?: number): Promise<void>;
2871
+ /**
2872
+ * Handle the full deposit-to-queue lifecycle for a lobby.
2873
+ *
2874
+ * After the deposit is confirmed, the backend may not have processed the
2875
+ * `lobby.deposit.allConfirmed` event yet, so the lobby can still be in
2876
+ * 'preparing' status. This method re-fetches the lobby and explicitly
2877
+ * joins the queue if needed, then pushes the latest state to the store
2878
+ * so the UI transitions immediately.
2879
+ */
2880
+ depositAndJoinQueue(lobbyId: string): Promise<DepositForLobbyResponse & {
2881
+ lobby: Lobby;
2882
+ }>;
2723
2883
  }
2724
2884
 
2725
2885
  /**
@@ -2757,16 +2917,16 @@ declare abstract class BaseWsTransport implements WsTransport {
2757
2917
  }
2758
2918
 
2759
2919
  declare class StandaloneWsTransport extends BaseWsTransport {
2920
+ private static readonly FAST_RETRY_LIMIT;
2921
+ private static readonly FAST_RETRY_DELAY_MS;
2922
+ private static readonly MAX_BACKOFF_MS;
2760
2923
  private socket;
2761
2924
  private url;
2762
2925
  private accessToken;
2763
2926
  private reconnectAttempts;
2764
2927
  private reconnectTimer;
2765
- private periodicReconnectInterval;
2766
- private maxReconnectAttempts;
2767
- private reconnectDelay;
2768
- private reconnectDelayMax;
2769
- private static readonly PERIODIC_RECONNECT_MS;
2928
+ private needsReconnect;
2929
+ private visibilityHandler;
2770
2930
  private wildcardHandlers;
2771
2931
  private eventHandlers;
2772
2932
  private registeredEvents;
@@ -2785,8 +2945,7 @@ declare class StandaloneWsTransport extends BaseWsTransport {
2785
2945
  private reconnectWithAuth;
2786
2946
  /** Clear socket reference so ensureSocket() can create a new connection. */
2787
2947
  private clearSocketForReconnect;
2788
- private clearPeriodicReconnect;
2789
- private startPeriodicReconnect;
2948
+ private reconnectImmediately;
2790
2949
  private scheduleReconnect;
2791
2950
  private getEventHandlers;
2792
2951
  private unsubscribeEvent;
@@ -2800,6 +2959,10 @@ declare class StandaloneWsTransport extends BaseWsTransport {
2800
2959
  declare class SharedWorkerTransport extends BaseWsTransport {
2801
2960
  private client;
2802
2961
  private url;
2962
+ /** Tracks whether a successful connection has been established at least once,
2963
+ * so that subsequent ws_open events are treated as reconnects and the
2964
+ * `connection:reconnected` event is dispatched to subscribers. */
2965
+ private hasConnectedBefore;
2803
2966
  constructor(workerUrl: string, socketUrl: string);
2804
2967
  connect(): void;
2805
2968
  disconnect(): void;
@@ -2843,4 +3006,4 @@ declare class HttpClient implements IHttpClient {
2843
3006
  private payChallenge;
2844
3007
  }
2845
3008
 
2846
- 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 DepositForLobbyResponse, 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 ImageUploadPayload, type InviteFriendRequest, type LeaderboardEntry, type LeaderboardQuery, type LeaderboardRange, type LeaderboardResponse, Leaderboards, type LivePlayer, type LivePlayersPage, Lobbies, type Lobby, type LobbyDepositUpdatedPayload, 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 PaginatedPlatformFees, type PaginatedReports, type PaginatedSearchUsers, type PaginatedSessions, type PaginatedSupportTickets, type PaginatedTransactionJobs, type PaginatedUsers, type PaymentRequiredChallenge, type PlatformFeeItem, 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 TransactionJob, type TransactionJobStatus, type TransactionJobType, type TransactionQueueStats, 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 };
3009
+ export { type AcceptChallengeResponse, type Achievement, Activity, type ActivityFeedItem, type ActivityFeedItemType, type ActivityFeedResponse, type ActivityFeedUser, Admin, type AdminDailyStats, type AdminDailyStatsItem, type AdminFeatureFlag, type AdminGameHistory, type AdminGameHistoryFeeBreakdown, type AdminGameHistoryFeePlayer, type AdminGameHistoryPlayer, type AdminMarketDailyStats, type AdminMarketDailyStatsItem, type AdminMarketDetail, type AdminMarketStats, type AdminStats, type AdminWalletActivityItem, type AdminWalletActivityResponse, type AnalyticsUserData, 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 DepositForLobbyResponse, 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 IAnalyticsClient, type IHttpClient, type ILogger, type IStorage, type ImageUploadPayload, type InviteFriendRequest, type LeaderboardEntry, type LeaderboardQuery, type LeaderboardRange, type LeaderboardResponse, Leaderboards, type LivePlayer, type LivePlayersPage, Lobbies, type Lobby, type LobbyDepositUpdatedPayload, 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, NoopAnalyticsClient, type NotificationEvent, type NotificationsStore, type NotificationsStoreState, type PaginatedCriticalIncidents, type PaginatedFriendRequests, type PaginatedFriends, type PaginatedNotificationsResponse, type PaginatedPlatformFees, type PaginatedReports, type PaginatedSearchUsers, type PaginatedSessions, type PaginatedSupportTickets, type PaginatedTransactionJobs, type PaginatedUsers, type PaymentRequiredChallenge, type PlatformFeeItem, 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, type SessionStats, 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 TransactionJob, type TransactionJobStatus, type TransactionJobType, type TransactionQueueStats, 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 };