@smartico/public-api 0.0.380 → 0.0.382

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