@smartico/public-api 0.0.379 → 0.0.380

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.
Files changed (99) hide show
  1. package/.nvmrc +1 -1
  2. package/README.md +31 -2
  3. package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
  4. package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
  5. package/dist/WSAPI/WSAPI.d.ts +13 -1235
  6. package/dist/WSAPI/WSAPIAvatars.d.ts +78 -0
  7. package/dist/WSAPI/WSAPIBase.d.ts +71 -0
  8. package/dist/WSAPI/WSAPIBonuses.d.ts +26 -0
  9. package/dist/WSAPI/WSAPIClans.d.ts +388 -0
  10. package/dist/WSAPI/WSAPIGamePick.d.ts +308 -0
  11. package/dist/WSAPI/WSAPIGeneral.d.ts +30 -0
  12. package/dist/WSAPI/WSAPIInbox.d.ts +126 -0
  13. package/dist/WSAPI/WSAPIJackpots.d.ts +109 -0
  14. package/dist/WSAPI/WSAPILeaderBoard.d.ts +25 -0
  15. package/dist/WSAPI/WSAPIMiniGames.d.ts +94 -0
  16. package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
  17. package/dist/WSAPI/WSAPIRaffles.d.ts +119 -0
  18. package/dist/WSAPI/WSAPIStore.d.ts +656 -0
  19. package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
  20. package/dist/WSAPI/WSAPITypes.d.ts +145 -85
  21. package/dist/WSAPI/WSAPIUser.d.ts +383 -0
  22. package/dist/index.js +3818 -1528
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.modern.mjs +3180 -981
  25. package/dist/index.modern.mjs.map +1 -1
  26. package/docs/api/README.md +56 -2
  27. package/docs/api/classes/WSAPIAvatars.md +116 -0
  28. package/docs/api/classes/WSAPIBonuses.md +50 -0
  29. package/docs/api/classes/WSAPIClans.md +66 -0
  30. package/docs/api/classes/WSAPIGamePick.md +181 -0
  31. package/docs/api/classes/WSAPIGeneral.md +63 -0
  32. package/docs/api/classes/WSAPIInbox.md +277 -0
  33. package/docs/api/classes/WSAPIJackpots.md +185 -0
  34. package/docs/api/classes/WSAPILeaderBoard.md +39 -0
  35. package/docs/api/classes/WSAPIMiniGames.md +175 -0
  36. package/docs/api/classes/WSAPIMissions.md +611 -0
  37. package/docs/api/classes/WSAPIRaffles.md +195 -0
  38. package/docs/api/classes/WSAPIStore.md +744 -0
  39. package/docs/api/classes/WSAPITournaments.md +104 -0
  40. package/docs/api/classes/WSAPIUser.md +200 -0
  41. package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
  42. package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
  43. package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
  44. package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
  45. package/docs/api/interfaces/ClanPublicMeta.md +4 -0
  46. package/docs/api/interfaces/SAWTemplateUI.md +10 -0
  47. package/docs/api/interfaces/TAchCategory.md +19 -4
  48. package/docs/api/interfaces/TBuyStoreItemResult.md +26 -8
  49. package/docs/api/interfaces/TMissionClaimRewardResult.md +14 -3
  50. package/docs/api/interfaces/TMissionOptInResult.md +10 -3
  51. package/docs/api/interfaces/TMissionOrBadge.md +6 -2
  52. package/docs/api/interfaces/TStoreItem.md +21 -1
  53. package/docs/api/interfaces/TTournamentDetailed.md +8 -0
  54. package/docs/api/interfaces/UserAchievement.md +1 -1
  55. package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
  56. package/docs/ui/clans/UIGuide_getClans.md +172 -0
  57. package/docs/ui/clans/UIGuide_joinClan.md +196 -0
  58. package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
  59. package/docs/ui/missions/UIGuide_getBadges.md +237 -0
  60. package/docs/ui/missions/UIGuide_getMissions.md +268 -0
  61. package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
  62. package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
  63. package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
  64. package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
  65. package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
  66. package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
  67. package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
  68. package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
  69. package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
  70. package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
  71. package/docs/ui/user/UIGuide_getLevels.md +162 -0
  72. package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
  73. package/package.json +3 -3
  74. package/scripts/postdoc-cleanup.js +195 -0
  75. package/src/Missions/MissionsUtils.ts +5 -2
  76. package/src/Store/BuyStoreItemErrorCode.ts +8 -0
  77. package/src/Store/StoreItem.ts +1 -0
  78. package/src/Store/StoreItemPurchased.ts +1 -0
  79. package/src/Store/StoreItemType.ts +1 -1
  80. package/src/Tournaments/TournamentRegistrationError.ts +4 -0
  81. package/src/WSAPI/WSAPI.ts +27 -2007
  82. package/src/WSAPI/WSAPIAvatars.ts +127 -0
  83. package/src/WSAPI/WSAPIBase.ts +93 -0
  84. package/src/WSAPI/WSAPIBonuses.ts +54 -0
  85. package/src/WSAPI/WSAPIClans.ts +417 -0
  86. package/src/WSAPI/WSAPIGamePick.ts +382 -0
  87. package/src/WSAPI/WSAPIGeneral.ts +57 -0
  88. package/src/WSAPI/WSAPIInbox.ts +222 -0
  89. package/src/WSAPI/WSAPIJackpots.ts +212 -0
  90. package/src/WSAPI/WSAPILeaderBoard.ts +40 -0
  91. package/src/WSAPI/WSAPIMiniGames.ts +181 -0
  92. package/src/WSAPI/WSAPIMissions.ts +572 -0
  93. package/src/WSAPI/WSAPIRaffles.ts +175 -0
  94. package/src/WSAPI/WSAPIStore.ts +732 -0
  95. package/src/WSAPI/WSAPITournaments.ts +541 -0
  96. package/src/WSAPI/WSAPITypes.ts +145 -87
  97. package/src/WSAPI/WSAPIUser.ts +456 -0
  98. package/tsconfig.json +17 -1
  99. package/docs/api/classes/WSAPI.md +0 -1927
@@ -0,0 +1,501 @@
1
+ import { TTournament, TTournamentDetailed, TTournamentRegistrationResult, TClanTournamentPlayers } from './WSAPITypes';
2
+ import { WSAPIStore } from './WSAPIStore';
3
+ /** @group Tournaments */
4
+ export declare class WSAPITournaments extends WSAPIStore {
5
+ /**
6
+ * Returns the list of tournaments currently visible to the user, scoped
7
+ * server-side to what the user's segments qualify them to see. Optionally
8
+ * subscribes to live updates via `onUpdate`: the callback is invoked with
9
+ * the full refreshed list whenever the user registers in a tournament.
10
+ *
11
+ * The returned list is the canonical source of truth for tournament
12
+ * lobby state (`is_user_registered`, `registration_status`,
13
+ * `is_in_progress`, `is_can_register`, etc.). Consumers should NOT
14
+ * mutate it optimistically — always wait for the `onUpdate` callback
15
+ * (or a fresh fetch after the 30 s cache window) to observe new state.
16
+ *
17
+ * @remarks
18
+ * **Subscription model (`onUpdate`)**
19
+ * The callback receives the FULL refreshed list (never a diff/patch).
20
+ * Each subsequent call to `getTournamentsList({ onUpdate })` REPLACES
21
+ * the prior callback — only one active subscriber at a time. Pass
22
+ * `onUpdate: undefined` (or omit it) to keep the prior callback in
23
+ * place; the callback is never auto-cleared.
24
+ *
25
+ * **Update triggers** — the callback fires when:
26
+ *
27
+ * 1. `registerInTournament(...)` resolves on this connection (any
28
+ * `err_code`). The refreshed list reflects the new
29
+ * `is_user_registered` / `registration_status` /
30
+ * `registration_count` on the affected tournament.
31
+ *
32
+ * Does NOT fire for: tournament lifecycle transitions (start, finish,
33
+ * cancellation), score updates, other users' registrations, or
34
+ * operator-side BO edits. Those changes surface only on the next
35
+ * cache miss (after the 30 s TTL) — poll manually if your UI needs
36
+ * sub-30s lifecycle freshness.
37
+ *
38
+ * **Server-side filtering** (what's excluded before the SDK sees it)
39
+ * The server filters by visibility segment and entry segment, removes
40
+ * tournaments past their post-finish display window, and excludes
41
+ * tournaments not yet published. SDK consumers receive only items
42
+ * the user is eligible to see; no client-side gating is required.
43
+ *
44
+ * **Reading state from the returned item**
45
+ * Drive list bucketing and CTA labels from the SDK-computed booleans
46
+ * (`is_active`, `is_can_register`, `is_cancelled`, `is_finished`,
47
+ * `is_in_progress`, `is_upcoming`), NOT from raw `start_time` /
48
+ * `end_time` comparisons — the booleans encode the canonical
49
+ * lifecycle states and already reflect server-side rules around
50
+ * qualifying scores and late registration. `is_user_registered` is
51
+ * independent of `is_can_register` — a registered user has
52
+ * `is_user_registered: true` and `is_can_register: false`. The `me`
53
+ * block (if present) carries the user's own leaderboard position and
54
+ * score; it's undefined for unregistered users, users without any
55
+ * recorded score, and visitor-mode sessions. The `prize_pool_short`
56
+ * field carries the operator-supplied summary string ("$10,000",
57
+ * "Mixed prizes") for compact card rendering; the full per-place
58
+ * `prizes[]` breakdown is also populated here but is typically
59
+ * rendered only in the detail view via
60
+ * {@link getTournamentInstanceInfo}.
61
+ *
62
+ * **Cross-references**
63
+ * Tournaments with `is_clan_based: true` group participants by clan —
64
+ * see {@link getClanTournamentPlayers} for fetching the players list
65
+ * of a specific clan within a clan tournament. The detailed lobby
66
+ * view (with full player leaderboard and prize structure) comes from
67
+ * {@link getTournamentInstanceInfo}. Tournaments with
68
+ * `custom_section_id` belong to an operator-defined custom section
69
+ * (resolve metadata via `getCustomSections()`).
70
+ *
71
+ * **Cache TTL**: the SDK caches the response for 30 seconds. Cache is
72
+ * fully cleared on login / logout.
73
+ *
74
+ * **Idempotency**: safe. Read-only. Repeated calls within the cache
75
+ * window return a deep-cloned cached array without a network
76
+ * round-trip.
77
+ *
78
+ * **Side effects**: none — pure metadata read.
79
+ *
80
+ * **UI guidance**: see [UI Guide — `getTournamentsList`](../../docs/ui/tournaments/UIGuide_getTournamentsList.md).
81
+ *
82
+ * **Visitor mode**: supported. The same shape is returned, scoped to
83
+ * the brand's public tournament list. Per-user fields (`me`,
84
+ * `is_user_registered`, `registration_status`) are not meaningful.
85
+ * The `onUpdate` callback is accepted but never fires (registration
86
+ * mutations are not supported in visitor mode).
87
+ *
88
+ * @param params Optional. Omit to fetch without subscribing.
89
+ * @param params.onUpdate Callback invoked with the full refreshed
90
+ * tournament list after every
91
+ * {@link registerInTournament} round-trip on
92
+ * this connection. Each call overwrites the
93
+ * prior callback. Never fires in visitor mode.
94
+ * @returns Promise resolving to the array of
95
+ * tournaments visible to the user. Empty
96
+ * array if no tournaments are visible.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const tournaments = await window._smartico.api.getTournamentsList({
101
+ * onUpdate: (refreshed) => {
102
+ * console.log('[smartico] tournament list refreshed — re-render the lobby UI from this array, do not merge with prior state:', refreshed);
103
+ * const justRegistered = refreshed.filter(t => t.is_user_registered);
104
+ * console.log('[smartico] user is now registered in these tournaments:', justRegistered.map(t => t.name));
105
+ * },
106
+ * });
107
+ *
108
+ * // Bucket items by lifecycle state for a tabbed UI.
109
+ * const live = tournaments.filter(t => t.is_in_progress);
110
+ * const upcoming = tournaments
111
+ * .filter(t => t.is_upcoming && !t.is_user_registered)
112
+ * .sort((a, b) => a.start_time - b.start_time);
113
+ * const mine = tournaments.filter(t => t.is_user_registered);
114
+ * const finished = tournaments.filter(t => t.is_finished);
115
+ *
116
+ * console.log('[smartico] render lobby tabs with these counts: live=', live.length,
117
+ * 'upcoming=', upcoming.length, 'mine=', mine.length, 'finished=', finished.length);
118
+ *
119
+ * // Featured tournament: pin to position 0 of the Overview/Top tabs.
120
+ * const featured = tournaments.find(t => t.is_featured && !t.is_cancelled);
121
+ * if (featured) {
122
+ * console.log('[smartico] featured tournament — pin to position 0 of the Overview tab:', featured.name);
123
+ * }
124
+ *
125
+ * // Visitor mode: onUpdate accepted but never fires; re-poll if needed.
126
+ * // const visitorList = await window._smartico.vapi('EN').getTournamentsList();
127
+ * ```
128
+ */
129
+ getTournamentsList({ onUpdate }?: {
130
+ onUpdate?: (data: TTournament[]) => void;
131
+ }): Promise<TTournament[]>;
132
+ /**
133
+ * Returns the full detail of a single tournament instance — adds the
134
+ * player leaderboard, the full prize structure, and (for clan
135
+ * tournaments) the clan leaderboard and per-clan prize structure on
136
+ * top of everything already in `TTournament`. Use this to power a
137
+ * tournament detail / lobby screen after the user picks an item from
138
+ * {@link getTournamentsList}.
139
+ *
140
+ * Live leaderboard updates require manual re-fetching — there is no
141
+ * subscription model, no push event, and no client-side cache (each
142
+ * call hits the server). The default Smartico UI polls every 3 seconds
143
+ * while the detail view is open.
144
+ *
145
+ * @remarks
146
+ * **Preconditions**
147
+ * Pass a valid `tournamentInstanceId` read from `TTournament.instance_id`
148
+ * on an item returned by {@link getTournamentsList}. The method works
149
+ * standalone — calling `getTournamentsList()` first is not required by
150
+ * the SDK, but is the only stable source of valid IDs.
151
+ *
152
+ * **Refresh model**
153
+ * - **No subscription.** This is a one-shot promise; call again to
154
+ * refresh.
155
+ * - **No client cache.** Every call sends a network request and
156
+ * returns the latest server snapshot. Safe to poll on an interval —
157
+ * the default Smartico UI uses 3 s while the detail view is visible.
158
+ * - **No push event** invalidates or refreshes detail state. Score
159
+ * changes, registration count changes, lifecycle transitions — all
160
+ * require a fresh `getTournamentInstanceInfo` call.
161
+ *
162
+ * **Returned shape — beyond `TTournament`**
163
+ * `TTournamentDetailed` extends `TTournament` with the following
164
+ * additional data: a `players[]` leaderboard sorted server-side by
165
+ * score (only members with at least one recorded score); the user's
166
+ * own `me` block carrying their rank and score (undefined when not
167
+ * registered or when the user has no score yet); a full per-place
168
+ * `prizes[]` array (place range, type, points / gems / diamonds
169
+ * amounts, image, name); and `related_games[]` if the operator has
170
+ * associated games with this tournament. For clan tournaments
171
+ * (`is_clan_based === true`), the response also carries
172
+ * `clan_leaderboard[]` (ranked clans with `total_score` and
173
+ * `contributing_members`), `clan_prize_structure[]` (per-clan-place
174
+ * prize tiers — Fixed vs Dynamic, with ScoreWeighted /
175
+ * EqualSplit distribution for Dynamic prizes), `user_clan_id` (the
176
+ * user's own clan), and the advisory `user_position_in_clan` /
177
+ * `user_score_in_clan` fields.
178
+ *
179
+ * **Idempotency**: safe. Read-only. Each call returns the latest
180
+ * server snapshot.
181
+ *
182
+ * **Side effects**: none — pure metadata read.
183
+ *
184
+ * **UI guidance**: see [UI Guide — `getTournamentInstanceInfo`](../../docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md).
185
+ *
186
+ * **Visitor mode**: not supported. Use {@link getTournamentsList} for
187
+ * the public lobby list in visitor mode; the detail endpoint requires
188
+ * an authenticated session.
189
+ *
190
+ * @param tournamentInstanceId The `instance_id` from a `TTournament`
191
+ * returned by {@link getTournamentsList}.
192
+ * @returns Promise resolving to `TTournamentDetailed`.
193
+ * Rejects if the instance ID is invalid
194
+ * or the user lacks visibility for it.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * const tournaments = await window._smartico.api.getTournamentsList();
199
+ * const tournament = tournaments[0];
200
+ *
201
+ * console.log('[smartico] loading detail view for tournament', tournament.instance_id);
202
+ * const detail = await window._smartico.api.getTournamentInstanceInfo(tournament.instance_id);
203
+ *
204
+ * console.log('[smartico] render detail with', detail.players?.length ?? 0,
205
+ * 'players,', detail.prizes?.length ?? 0, 'prize tiers');
206
+ *
207
+ * if (detail.is_clan_based && detail.clan_leaderboard) {
208
+ * console.log('[smartico] clan tournament — render clan leaderboard tab with',
209
+ * detail.clan_leaderboard.length, 'clans');
210
+ * if (detail.user_clan_id != null) {
211
+ * console.log('[smartico] user belongs to clan', detail.user_clan_id,
212
+ * '— highlight that row in the clan leaderboard');
213
+ * }
214
+ * }
215
+ *
216
+ * // Live leaderboard updates — poll every 3 seconds while the detail view is open.
217
+ * const pollId = setInterval(async () => {
218
+ * try {
219
+ * const fresh = await window._smartico.api.getTournamentInstanceInfo(tournament.instance_id);
220
+ * console.log('[smartico] detail refreshed — re-render player + clan leaderboards from this new snapshot:', fresh);
221
+ * } catch (e) {
222
+ * console.error('[smartico] tournament detail poll failed — keep showing last snapshot, retry on next tick:', e);
223
+ * }
224
+ * }, 3_000);
225
+ * // clearInterval(pollId) when the detail view closes.
226
+ *
227
+ * if (detail.me) {
228
+ * console.log('[smartico] current user is rank', detail.me.position,
229
+ * 'with', detail.me.scores, 'points — render the sticky "me" panel below the leaderboard');
230
+ * }
231
+ * ```
232
+ */
233
+ getTournamentInstanceInfo(tournamentInstanceId: number): Promise<TTournamentDetailed>;
234
+ /**
235
+ * Returns the ranked players of a specific clan within a clan-based
236
+ * tournament instance. Used to drill down from the clan-leaderboard
237
+ * tab on the tournament detail view into a single clan's member
238
+ * roster.
239
+ *
240
+ * The server returns up to roughly 20 players (top-N by score
241
+ * descending). Server-side ordering is already by `scores` DESC
242
+ * (equivalent to `position` ASC) — no client-side re-sort is
243
+ * required.
244
+ *
245
+ * @remarks
246
+ * **Preconditions**
247
+ * Pass a valid `tournamentInstanceId` (read from `TTournament.instance_id`
248
+ * returned by {@link getTournamentsList}) and a `clanId` (read from
249
+ * `TTournamentDetailed.clan_leaderboard[].clan_id` returned by
250
+ * {@link getTournamentInstanceInfo}). The tournament should be
251
+ * clan-based (`is_clan_based === true`); calling this against a
252
+ * non-clan tournament typically returns an empty `players` array.
253
+ *
254
+ * **Refresh model**
255
+ * - **No subscription.** This is a one-shot promise.
256
+ * - **No client cache.** Every call hits the server.
257
+ * - **No push event** refreshes the response. Live updates to clan
258
+ * member rankings require a fresh call.
259
+ * - The default Smartico UI fetches this once when the user opens the
260
+ * clan-drill-down modal and does NOT refresh while the modal is
261
+ * open. If your UI needs live updates, re-call on an interval; the
262
+ * clan leaderboard at the parent level (via
263
+ * {@link getTournamentInstanceInfo}) does refresh via its own
264
+ * polling cadence.
265
+ *
266
+ * **Returned shape**
267
+ * `TClanTournamentPlayers` carries the requested clan's identity
268
+ * (`clan_id`, `clan_public_meta.name`, `clan_public_meta.image_url`)
269
+ * alongside the `players[]` array — each entry has `position`,
270
+ * `scores`, `public_username`, `clean_ext_user_id`, `avatar_id`,
271
+ * `avatar_real_id`, the resolved `avatar_url`, `user_id`, and the
272
+ * `is_me` flag identifying the current user's row. The `clan_id` and
273
+ * `clan_public_meta` on the response echo the input clan — the
274
+ * default Smartico UI ignores them and renders the header from the
275
+ * caller-side `ClanLeaderboardEntry` object, but they're available
276
+ * for consumers that don't already have that context.
277
+ *
278
+ * **Username display**: prefer `clean_ext_user_id` when set, falling
279
+ * back to `public_username`. The default Smartico UI uses
280
+ * `clean_ext_user_id || public_username || ''`.
281
+ *
282
+ * **Idempotency**: safe. Read-only. Each call returns the latest
283
+ * server snapshot.
284
+ *
285
+ * **Side effects**: none — pure metadata read.
286
+ *
287
+ * **UI guidance**: see [UI Guide — `getClanTournamentPlayers`](../../docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md).
288
+ *
289
+ * **Visitor mode**: not supported.
290
+ *
291
+ * @param tournamentInstanceId The tournament `instance_id` from a
292
+ * clan-based `TTournament`.
293
+ * @param clanId The clan ID from
294
+ * `TTournamentDetailed.clan_leaderboard[].clan_id`.
295
+ * @returns Promise resolving to
296
+ * `TClanTournamentPlayers`. An invalid
297
+ * ID combination typically yields an
298
+ * empty `players` array; the SDK does
299
+ * not distinguish "no scores yet" from
300
+ * "invalid IDs" — both manifest as an
301
+ * empty list.
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * const detail = await window._smartico.api.getTournamentInstanceInfo(tournamentInstanceId);
306
+ * if (!detail.is_clan_based || !detail.clan_leaderboard) {
307
+ * console.log('[smartico] not a clan tournament — skip clan drill-down');
308
+ * return;
309
+ * }
310
+ *
311
+ * // User clicked a clan row in the leaderboard.
312
+ * const clickedClan = detail.clan_leaderboard[0];
313
+ *
314
+ * console.log('[smartico] opening clan drill-down — show modal skeleton while loading');
315
+ * const result = await window._smartico.api.getClanTournamentPlayers(
316
+ * tournamentInstanceId,
317
+ * clickedClan.clan_id,
318
+ * );
319
+ *
320
+ * if (result.players.length === 0) {
321
+ * console.log('[smartico] clan has no ranked players yet — render empty state ("No leaders yet")');
322
+ * } else {
323
+ * console.log('[smartico] render clan member rows with .is-me highlight on the current user;',
324
+ * result.players.length, 'players ranked');
325
+ * const me = result.players.find(p => p.is_me);
326
+ * if (me) {
327
+ * console.log('[smartico] current user rank in this clan:', me.position, 'score:', me.scores);
328
+ * }
329
+ * }
330
+ * ```
331
+ */
332
+ getClanTournamentPlayers(tournamentInstanceId: number, clanId: number): Promise<TClanTournamentPlayers>;
333
+ /**
334
+ * Registers the authenticated user in the specified tournament instance.
335
+ * For tournaments with a buy-in cost, the user's balance is debited
336
+ * synchronously before the response is returned; for free tournaments
337
+ * the call is a simple membership add.
338
+ *
339
+ * A successful response (`err_code === 0`) means the registration row
340
+ * exists server-side, the buy-in (if any) has been deducted, and the
341
+ * SDK has already triggered a refresh of the tournament lobby cache.
342
+ *
343
+ * @remarks
344
+ * **Preconditions**
345
+ * Read the candidate from {@link getTournamentsList} and gate the call
346
+ * on `is_can_register === true`. This composite flag already encodes:
347
+ * not already registered, slot available
348
+ * (`registration_count < players_max_count`), tournament status is
349
+ * REGISTER (or STARTED with late-registration enabled), and the
350
+ * registration type is not AUTO. The SDK forwards the call
351
+ * unconditionally — calling without satisfying these will return one
352
+ * of the error codes below.
353
+ *
354
+ * For clan tournaments (`is_clan_based === true`), the user must
355
+ * already belong to a clan before calling. If they don't, prompt them
356
+ * to pick a clan first via {@link joinClan}, then call
357
+ * `registerInTournament` after the clan-join resolves. See "Error
358
+ * codes" `1010` below for the server-side safety net.
359
+ *
360
+ * **Error codes** (in `err_code`, typed as {@link TournamentRegistrationError})
361
+ * - `0` — success; the registration is persisted, buy-in deducted,
362
+ * tournament lobby refresh fires.
363
+ * - `1010` — `TOURNAMENT_USER_CANNOT_JOIN_WITHOUT_CLAN`: clan-based
364
+ * tournament and the user has no clan. Surface the clan-pick flow
365
+ * (e.g. open a clan-pick modal driven by {@link getClans} +
366
+ * {@link joinClan}), then retry registration.
367
+ * - `30001` — `TOURNAMENT_INSTANCE_NOT_FOUND`: instance ID is invalid
368
+ * or the tournament was deleted. Refresh the lobby via
369
+ * `getTournamentsList()` and hide the entry from the UI.
370
+ * - `30002` — `TOURNAMENT_REGISTRATION_NOT_ENOUGH_POINTS`: insufficient
371
+ * points balance for a points-cost tournament. Show an
372
+ * insufficient-balance UI naming the deficit.
373
+ * - `30003` — `TOURNAMENT_INSTANCE_NOT_IN_STATE`: tournament is no
374
+ * longer in a registerable state (finished, cancelled, finalizing,
375
+ * or not yet published with late registration disabled). Refresh
376
+ * the lobby; the button should hide.
377
+ * - `30004` — `TOURNAMENT_ALREADY_REGISTERED`: user is already
378
+ * registered. Treat as idempotent success — hide the Register button
379
+ * and refresh the lobby. Usually indicates a stale local state
380
+ * (e.g. registered from another tab).
381
+ * - `30005` — `TOURNAMENT_USER_DONT_MATCH_CONDITIONS`: user fails the
382
+ * tournament's segment / entry conditions. Prefer
383
+ * `tournament.segment_dont_match_message` (operator-supplied) over
384
+ * `err_message` when both are available.
385
+ * - `30006` — `TOURNAMENT_USER_NOT_REGISTERED`: anomalous on a fresh
386
+ * register call; usually indicates a server-side race. Treat as a
387
+ * generic transient error.
388
+ * - `30007` — `TOURNAMENT_CANT_CHANGE_REGISTRATION_STATUS`: status
389
+ * transition not allowed (e.g. re-registering after a finished /
390
+ * cancelled tournament). Show a generic error; do not retry.
391
+ * - `30008` — `TOURNAMENT_MAX_REGISTRATIONS_REACHED`: the tournament
392
+ * filled up between the lobby fetch and the registration click.
393
+ * Refresh the lobby — the button will hide on the refreshed item.
394
+ * - `300010` — insufficient **gems** balance (gems-cost tournament).
395
+ * Same UI handling as `30002` but for the gems currency.
396
+ * - `300011` — insufficient **diamonds** balance (diamonds-cost
397
+ * tournament). Same as `300010` but for diamonds.
398
+ * - other non-zero — generic server error. Surface `err_message` if any.
399
+ *
400
+ * Note: clan-tournament registration can occasionally surface error
401
+ * codes from the clan-join domain (e.g. `1011` — joined-after-start)
402
+ * via the same response path. These are members of `JoinClanErrorCode`,
403
+ * not `TournamentRegistrationError`. Branch on the numeric value.
404
+ *
405
+ * **Idempotency**: NOT idempotent. A second call on the same instance
406
+ * returns `30004` once the first call has succeeded. The SDK does NOT
407
+ * enforce an in-flight lock. The consumer MUST guard the call site
408
+ * against double-clicks (set a local "registering" flag on click, clear
409
+ * it on response).
410
+ *
411
+ * **Refresh after success (and after failure)**
412
+ * The SDK automatically refreshes the tournament lobby cache on every
413
+ * response (success OR error) and fires any `onUpdate` callback
414
+ * registered via `getTournamentsList({ onUpdate })`. After
415
+ * `err_code === 0`, the affected item's `is_user_registered` /
416
+ * `registration_status` / `registration_count` reflect the new
417
+ * registered state on the refreshed array. Note that
418
+ * {@link getTournamentInstanceInfo} is NOT auto-refreshed — if the
419
+ * detail screen is open, call it again manually.
420
+ *
421
+ * The user's balance (points / gems / diamonds) is exposed on the
422
+ * user-properties channel and updates independently of this call's
423
+ * response — subscribe to user-property updates separately if your UI
424
+ * shows the balance.
425
+ *
426
+ * **Side effects** (consumer-observable on success)
427
+ * - Balance debited synchronously by the buy-in amount in the
428
+ * tournament's currency (`registration_cost_points`,
429
+ * `registration_cost_gems`, or `registration_cost_diamonds`). For
430
+ * free tournaments no deduction occurs.
431
+ * - Server-side analytics events fire downstream
432
+ * (`tournament_user_registered` for immediate-registration types;
433
+ * `tournament_user_registration_pending` or
434
+ * `tournament_registered_pending_qualification` for
435
+ * manual-approval / qualification-based types).
436
+ * - Any operator-configured on-join prizes are distributed (e.g.
437
+ * welcome bonus). These surface via the relevant follow-up channels
438
+ * (e.g. {@link getBonuses}).
439
+ *
440
+ * **UI guidance**: see [UI Guide — `registerInTournament`](../../docs/ui/tournaments/UIGuide_registerInTournament.md).
441
+ *
442
+ * **Visitor mode**: not supported. Calling from a visitor session
443
+ * returns a generic error, not a typed `TournamentRegistrationError`.
444
+ *
445
+ * @param tournamentInstanceId The `instance_id` from `TTournament`
446
+ * (NOT the template `tournament_id`).
447
+ * @returns `{ err_code, err_message }`; success when `err_code === 0`
448
+ * (or `30004` when treated as idempotent no-op).
449
+ *
450
+ * @example
451
+ * ```ts
452
+ * const tournaments = await window._smartico.api.getTournamentsList({
453
+ * onUpdate: (refreshed) => console.log('[smartico] tournament list updated — re-render lobby from this array', refreshed),
454
+ * });
455
+ * const tournament = tournaments.find(t => t.instance_id === instanceId);
456
+ *
457
+ * if (!tournament) {
458
+ * console.log('[smartico] tournament not in current lobby — refresh getTournamentsList and retry');
459
+ * return;
460
+ * }
461
+ * if (!tournament.is_can_register) {
462
+ * console.log('[smartico] tournament not currently registerable — keep CTA disabled');
463
+ * return;
464
+ * }
465
+ *
466
+ * // Clan tournament + user has no clan → resolve clan first.
467
+ * if (tournament.is_clan_based) {
468
+ * const userProfile = window._smartico.api.getUserProfile();
469
+ * const userClanId = userProfile?.clan_id;
470
+ * if (userClanId == null) {
471
+ * console.log('[smartico] clan tournament — open the clan-pick modal first; after joinClan resolves, call registerInTournament again');
472
+ * return;
473
+ * }
474
+ * }
475
+ *
476
+ * console.log('[smartico] registration starting — set in-flight flag, show loading dots on the Join button, keep modal open');
477
+ * const r = await window._smartico.api.registerInTournament(tournament.instance_id);
478
+ * console.log('[smartico] registration response received — clear in-flight flag');
479
+ *
480
+ * if (r.err_code === 0 || r.err_code === 30004) {
481
+ * console.log('[smartico] registered (or was already) — close any modal, show a success toast; getTournamentsList onUpdate above will fire with the refreshed array');
482
+ * } else if (r.err_code === 1010) {
483
+ * console.log('[smartico] clan required — open the clan-pick modal again (this is the server-side safety net for a clan-leave race)');
484
+ * } else if (r.err_code === 30002) {
485
+ * console.error('[smartico] insufficient points — show insufficient-balance UI; deficit:', tournament.registration_cost_points);
486
+ * } else if (r.err_code === 300010) {
487
+ * console.error('[smartico] insufficient gems — show insufficient-balance UI; deficit:', tournament.registration_cost_gems);
488
+ * } else if (r.err_code === 300011) {
489
+ * console.error('[smartico] insufficient diamonds — show insufficient-balance UI; deficit:', tournament.registration_cost_diamonds);
490
+ * } else if (r.err_code === 30005) {
491
+ * console.error('[smartico] segment mismatch — prefer the operator-supplied message:', tournament.segment_dont_match_message || r.err_message);
492
+ * } else if (r.err_code === 30008) {
493
+ * console.error('[smartico] tournament full — auto-refresh will hide the button on the refreshed lobby item');
494
+ * } else {
495
+ * console.error('[smartico] registration failed — show a generic error toast with this message:', r.err_message);
496
+ * }
497
+ * ```
498
+ */
499
+ registerInTournament(tournamentInstanceId: number): Promise<TTournamentRegistrationResult>;
500
+ protected updateTournaments(): Promise<void>;
501
+ }