@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
@@ -9,6 +9,7 @@ import {
9
9
  import {
10
10
  drawRunHistoryTransform,
11
11
  raffleClaimPrizeResponseTransform,
12
+ GetRaffleWonPrizesResponse,
12
13
  } from '../Raffle';
13
14
  import {
14
15
  CACHE_DATA_SEC,
@@ -24,28 +25,113 @@ export class WSAPIRaffles extends WSAPIJackpots {
24
25
  }
25
26
 
26
27
  /**
27
- * Returns the list of Raffles available for user
28
- * The returned list of Raffles is cached for 30 seconds. But you can pass the onUpdate callback as a parameter. Note that each time you call getRaffles with a new onUpdate callback, the old one will be overwritten by the new one.
29
- * The onUpdate callback will be called on claiming prize. Updated Raffles will be passed to onUpdate callback.
28
+ * Returns all raffles visible to the current user, each carrying an
29
+ * embedded `draws[]` array with per-draw state (current state, ticket
30
+ * counts, opt-in status, prize structure). Use this to power a
31
+ * raffles lobby screen and to drive per-draw CTAs (opt-in, view
32
+ * winners, claim).
30
33
  *
31
- * **Example**:
32
- *
33
- * ```
34
- * _smartico.api.getRaffles().then((result) => {
35
- * console.log(result);
36
- * });
37
- * ```
34
+ * The embedded `draws[i]` objects are sufficient for rendering all
35
+ * draw cards — winner details with usernames / avatars require a
36
+ * follow-up {@link getRaffleDrawRun} call (the embedded form carries
37
+ * only `winners_total` / `winners_limit` / `winners_offset` metadata,
38
+ * not individual winner rows).
38
39
  *
39
- * **Example in the Visitor mode**:
40
- *
41
- * ```
42
- * _smartico.vapi('EN').getRaffles().then((result) => {
43
- * console.log(result);
40
+ * @remarks
41
+ * **Subscription model (`onUpdate`)**
42
+ * The callback receives the FULL refreshed raffle list (never a
43
+ * diff/patch). Each subsequent call to `getRaffles({ onUpdate })`
44
+ * REPLACES the prior callback. Pass `onUpdate: undefined` (or omit
45
+ * it) to keep the prior callback in place; the callback is never
46
+ * auto-cleared.
47
+ *
48
+ * **Update triggers** — the callback fires when:
49
+ *
50
+ * 1. {@link claimRafflePrize} resolves on this connection (any
51
+ * response code) — the refreshed list reflects the new
52
+ * `has_unclaimed_prize` / `claimed_date` state.
53
+ * 2. {@link requestRaffleOptin} resolves on this connection (any
54
+ * response code) — the refreshed list reflects the new
55
+ * `user_opted_in` state on the affected draw.
56
+ *
57
+ * Does NOT fire for: server-side draw executions, ticket increments
58
+ * (other users earning tickets), or operator-side raffle/draw config
59
+ * changes. Those changes surface only on the next cache miss (after
60
+ * the 30 s TTL) — poll manually if your UI needs sub-30s freshness
61
+ * during an in-progress draw.
62
+ *
63
+ * **Reading state from the returned raffle**
64
+ * - `current_tickets_count` vs `max_tickets_count` drives the
65
+ * `ticket_cap_visualization` banner (enum
66
+ * {@link RaffleTicketCapVisualization}: `Empty` = no banner,
67
+ * `Counter` = show "X tickets remaining", `Message` = show
68
+ * sold-out message).
69
+ * - Within each draw, `current_state`
70
+ * ({@link RaffleDrawInstanceState}) buckets the draw into Open
71
+ * (accepting tickets), WinnerSelection (currently drawing), or
72
+ * Executed (winners selected).
73
+ * - `execution_type` ({@link RaffleDrawTypeExecution}) distinguishes
74
+ * one-shot (`ExecDate`), repeating (`Recurring`), or special
75
+ * one-shot (`Grand`) draws. Recurring draws share a stable
76
+ * `draws[i].id` (the schedule definition) across runs — `run_id`
77
+ * is the per-execution instance.
78
+ *
79
+ * **Cache TTL**: the SDK caches the response for 30 seconds. Cache
80
+ * is fully cleared on login / logout. The server also invalidates
81
+ * the SDK cache when a draw executes on the server side.
82
+ *
83
+ * **Idempotency / Side effects**: safe. Read-only.
84
+ *
85
+ * **UI guidance**: see [UI Guide — `getRaffles`](../../docs/ui/raffles/UIGuide_getRaffles.md).
86
+ *
87
+ * **Visitor mode**: supported. The same shape is returned, scoped
88
+ * to the brand's public raffles. Per-user fields (`my_tickets_count`,
89
+ * `my_last_tickets`, `user_opted_in`) are not meaningful for
90
+ * visitors. The `onUpdate` callback is accepted but never fires
91
+ * because the mutation methods that trigger it
92
+ * ({@link claimRafflePrize}, {@link requestRaffleOptin}) are not
93
+ * available / not effective in visitor mode.
94
+ *
95
+ * @param params Optional. Omit to fetch without subscribing.
96
+ * @param params.onUpdate Callback invoked with the full refreshed
97
+ * raffles list after every
98
+ * {@link claimRafflePrize} or
99
+ * {@link requestRaffleOptin} round-trip
100
+ * on this connection.
101
+ * @returns Promise resolving to the raffles list.
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const raffles = await window._smartico.api.getRaffles({
106
+ * onUpdate: (refreshed) => {
107
+ * console.log('[smartico] raffles refreshed (after claim/optin) — re-render from this array:', refreshed);
108
+ * },
44
109
  * });
45
- * ```
46
110
  *
111
+ * for (const raffle of raffles) {
112
+ * console.log('[smartico] render raffle', raffle.id, '—', raffle.name, ':', raffle.draws.length, 'draws');
113
+ *
114
+ * // Bucket draws: active/upcoming first (sorted by execution_ts ASC), then executed last.
115
+ * const sorted = [...raffle.draws].sort((a, b) => {
116
+ * const aDone = a.current_state === 3; // Executed
117
+ * const bDone = b.current_state === 3;
118
+ * if (aDone !== bDone) return aDone ? 1 : -1; // executed sink to the bottom
119
+ * return a.execution_ts - b.execution_ts;
120
+ * });
121
+ *
122
+ * for (const d of sorted) {
123
+ * if (d.requires_optin && !d.user_opted_in && d.is_active && d.current_state !== 3) {
124
+ * console.log('[smartico] draw', d.run_id, '— show OPT IN CTA (requires_optin + not yet opted in + still active)');
125
+ * }
126
+ * if (d.current_state === 3) {
127
+ * console.log('[smartico] draw', d.run_id, 'executed — fetch winner details via getRaffleDrawRun');
128
+ * }
129
+ * }
130
+ * }
131
+ *
132
+ * // For winner detail on an executed draw, call getRaffleDrawRun separately.
133
+ * ```
47
134
  */
48
-
49
135
  public async getRaffles({ onUpdate }: { onUpdate?: (data: TRaffle[]) => void } = {}): Promise<TRaffle[]> {
50
136
  if (onUpdate) {
51
137
  this.onUpdateCallback.set(onUpdateContextKey.Raffles, onUpdate);
@@ -55,29 +141,107 @@ export class WSAPIRaffles extends WSAPIJackpots {
55
141
  }
56
142
 
57
143
  /**
58
- * Returns draw run for provided raffle_id and run_id.
59
- * You can pass winners_from and winners_to parameters to get a specific range of winners. Default is 0-20.
144
+ * Returns the full detail of a single raffle draw run — same shape
145
+ * as the embedded `TRaffleDraw` in {@link getRaffles}, but populated
146
+ * with paginated `prizes[].winners[]` rows including usernames and
147
+ * avatars. Use this to render a draw detail / winners screen, or to
148
+ * page through the winner list of an executed draw.
60
149
  *
150
+ * Each call is a fresh server round-trip — there is no client cache.
151
+ * Re-call to refresh.
61
152
  *
62
- * **Example**:
63
- *
64
- * ```javascript
65
- * _smartico.api.getRaffleDrawRun({raffle_id: 156, run_id: 145}).then((result) => {
66
- * console.log(result);
67
- * });
68
- * ```
153
+ * @remarks
154
+ * **Preconditions**
155
+ * Pass `raffle_id` (the parent raffle's `id`) and `run_id` (the
156
+ * specific run instance — `TRaffleDraw.run_id` from
157
+ * {@link getRaffles}'s embedded draws). Note that
158
+ * `TRaffleDraw.id` is the *schedule_id* (stable across runs of a
159
+ * recurring draw) — that's NOT what this method takes; it takes the
160
+ * per-instance `run_id`.
161
+ *
162
+ * **Refresh model**
163
+ * - **No subscription.** One-shot promise.
164
+ * - **No client cache.** Every call sends a network request.
165
+ * - **No push event** refreshes the response. Live winner-list
166
+ * updates require a fresh call.
167
+ * - The default Smartico UI polls this method on a variable cadence
168
+ * while a draw is in flight: every 3 s during `WinnerSelection`,
169
+ * every 10 s when the countdown is under 5 minutes, every 30 s
170
+ * otherwise.
171
+ *
172
+ * **Winner pagination**
173
+ * `winners_from` / `winners_to` define a half-open range of winner
174
+ * indices. The default window is `0–20` (20 winners). The server
175
+ * caps the window at 50 rows per call — passing a larger range
176
+ * silently truncates. For "load more" pagination, advance
177
+ * `winners_from` by the prior page size and pass the same
178
+ * `winners_to` offset. `winners_total` on the returned
179
+ * `TRaffleDraw` is the authoritative total count for pagination.
180
+ *
181
+ * The current user's own winning rows (if any) are server-sorted
182
+ * to the top of the result.
183
+ *
184
+ * **Throws**
185
+ * Both `raffle_id` and `run_id` are required — the SDK throws
186
+ * synchronously when either is missing or falsy.
187
+ *
188
+ * **Idempotency / Side effects**: safe. Read-only.
189
+ *
190
+ * **UI guidance**: see [UI Guide — `getRaffleDrawRun`](../../docs/ui/raffles/UIGuide_getRaffleDrawRun.md).
69
191
  *
70
- * **Example in the Visitor mode**:
71
- *
72
- *
73
- * ```javascript
74
- * _smartico.vapi('EN').getRaffleDrawRun({ raffle_id: 156, run_id: 145 }).then((result) => {
75
- * console.log(result);
192
+ * **Visitor mode**: supported.
193
+ *
194
+ * @param props.raffle_id The parent raffle's `id` (from `TRaffle.id`).
195
+ * @param props.run_id The draw run instance ID (from
196
+ * `TRaffleDraw.run_id`, not `TRaffleDraw.id`).
197
+ * @param props.winners_from First winner index to return (0-based).
198
+ * Defaults to `0`.
199
+ * @param props.winners_to Last winner index (exclusive).
200
+ * Defaults to `20`. Server caps the
201
+ * window at 50 rows per call.
202
+ * @returns Promise resolving to `TRaffleDraw`
203
+ * with `prizes[].winners[]` populated
204
+ * and `winners_total` set.
205
+ *
206
+ * @example
207
+ * ```ts
208
+ * const raffles = await window._smartico.api.getRaffles();
209
+ * const raffle = raffles[0];
210
+ * const draw = raffle.draws.find(d => d.current_state === 3); // Executed
211
+ *
212
+ * if (!draw) {
213
+ * console.log('[smartico] no executed draw — skip detail view');
214
+ * return;
215
+ * }
216
+ *
217
+ * // First page of winners.
218
+ * const detail = await window._smartico.api.getRaffleDrawRun({
219
+ * raffle_id: raffle.id,
220
+ * run_id: draw.run_id, // NOTE: run_id, NOT draw.id
221
+ * winners_from: 0,
222
+ * winners_to: 20,
76
223
  * });
77
- * ```
78
224
  *
225
+ * for (const prize of detail.prizes) {
226
+ * console.log('[smartico] prize', prize.name, '— winners on this page:', prize.winners.length);
227
+ * const myWin = prize.winners.find(w => w.username === currentUsername); // or another match
228
+ * if (myWin) {
229
+ * console.log('[smartico] current user won this prize — surface a Claim CTA if not yet claimed');
230
+ * }
231
+ * }
232
+ *
233
+ * // Load more — pagination via winners_from / winners_to.
234
+ * if ((detail.winners_total ?? 0) > 20) {
235
+ * const next = await window._smartico.api.getRaffleDrawRun({
236
+ * raffle_id: raffle.id,
237
+ * run_id: draw.run_id,
238
+ * winners_from: 20,
239
+ * winners_to: 40,
240
+ * });
241
+ * console.log('[smartico] page 2 loaded — append', next.prizes.flatMap(p => p.winners).length, 'winners');
242
+ * }
243
+ * ```
79
244
  */
80
-
81
245
  public async getRaffleDrawRun(props: { raffle_id: number; run_id: number; winners_from?: number; winners_to?: number }): Promise<TRaffleDraw> {
82
246
  if (!props.raffle_id || !props.run_id) {
83
247
  throw new Error('both raffle_id and run_id are required');
@@ -87,27 +251,77 @@ export class WSAPIRaffles extends WSAPIJackpots {
87
251
  }
88
252
 
89
253
  /**
90
- * Returns history of draw runs for the provided raffle_id and draw_id, if the draw_id is not provided will return history of all the draws for the provided raffle_id
254
+ * Returns the history of past-executed draw runs for a raffle —
255
+ * optionally scoped to a single recurring draw schedule. Each row
256
+ * is a previously-executed run with its scheduled and
257
+ * actual-execution timestamps, the user's win status, and an
258
+ * unclaimed-prize flag for surfacing a Claim CTA on history rows.
259
+ *
260
+ * @remarks
261
+ * **Preconditions**
262
+ * `raffle_id` is required. `draw_id` is optional — when omitted,
263
+ * the response includes history for ALL draws of the raffle; when
264
+ * supplied, it scopes to that one draw's recurring history. The
265
+ * `draw_id` to pass is `TRaffleDraw.id` (the schedule_id, stable
266
+ * across runs), not `run_id`.
267
+ *
268
+ * **Server-side filtering**
269
+ * Draws configured by the operator to hide their history are
270
+ * excluded from the response automatically. Cancelled runs are
271
+ * also excluded.
272
+ *
273
+ * **Sort order**
274
+ * Server returns rows by scheduled `execution_ts` descending
275
+ * (newest first). No client-side sort required.
276
+ *
277
+ * **Refresh model**
278
+ * - **No subscription.** One-shot promise.
279
+ * - **No client cache.** Every call hits the server.
280
+ * - **No push event** refreshes the response. Re-call manually to
281
+ * pick up newly-executed runs or `has_unclaimed_prize` flips
282
+ * after a {@link claimRafflePrize} call.
283
+ *
284
+ * **Idempotency / Side effects**: safe. Read-only.
285
+ *
286
+ * **UI guidance**: see [UI Guide — `getRaffleDrawRunsHistory`](../../docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md).
91
287
  *
288
+ * **Visitor mode**: supported. The same shape is returned with
289
+ * `is_winner` and `has_unclaimed_prize` always `false` for visitors.
92
290
  *
93
- * **Example**:
94
- *
95
- * ```javascript
96
- * _smartico.api.getRaffleDrawRunsHistory({ raffle_id: 156, draw_id: 432 }).then((result) => {
97
- * console.log(result);
291
+ * @param props.raffle_id The parent raffle's `id` (from `TRaffle.id`).
292
+ * Required.
293
+ * @param props.draw_id Optional — the draw's schedule_id
294
+ * (`TRaffleDraw.id`). When set, scopes the
295
+ * history to that one draw's runs. When
296
+ * omitted, includes all draws of the raffle.
297
+ * @returns Promise resolving to a `TRaffleDrawRun[]`
298
+ * ordered newest-first. Empty if no executed
299
+ * runs exist.
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * const raffles = await window._smartico.api.getRaffles();
304
+ * const raffle = raffles[0];
305
+ *
306
+ * // History across all draws of the raffle.
307
+ * const allHistory = await window._smartico.api.getRaffleDrawRunsHistory({
308
+ * raffle_id: raffle.id,
98
309
  * });
99
- * ```
100
310
  *
101
- * **Example in the Visitor mode**:
102
- *
103
- * ```javascript
104
- * _smartico.vapi('EN').getRaffleDrawRunsHistory({ raffle_id: 156, draw_id: 432 }).then((result) => {
105
- * console.log(result);
311
+ * // Highlight rows where the user has an unclaimed prize.
312
+ * const unclaimed = allHistory.filter(r => r.has_unclaimed_prize);
313
+ * if (unclaimed.length > 0) {
314
+ * console.log('[smartico] surface a "Claim" CTA on these', unclaimed.length, 'history rows:', unclaimed.map(r => r.run_id));
315
+ * }
316
+ *
317
+ * // Scoped history of one recurring draw (use draw.id, the schedule_id).
318
+ * const oneDrawHistory = await window._smartico.api.getRaffleDrawRunsHistory({
319
+ * raffle_id: raffle.id,
320
+ * draw_id: raffle.draws[0].id, // schedule_id (stable across recurring runs)
106
321
  * });
322
+ * console.log('[smartico] render history rows for the daily draw — newest first:', oneDrawHistory.length, 'rows');
107
323
  * ```
108
- *
109
324
  */
110
-
111
325
  public async getRaffleDrawRunsHistory(props: { raffle_id: number; draw_id?: number }): Promise<TRaffleDrawRun[]> {
112
326
 
113
327
  const res = await this.api.getRaffleDrawRunsHistory(this.userExtId, props);
@@ -120,25 +334,113 @@ export class WSAPIRaffles extends WSAPIJackpots {
120
334
  }
121
335
 
122
336
  /**
123
- * Returns `err_code` and `err_message` after the call; `err_code` 0 means the request succeeded.
337
+ * Claims a raffle prize the user has won. Call this when the user
338
+ * has a winning row with `should_claim === true` and an unclaimed
339
+ * `won_id` (read from a `TRafflePrizeWinner` on a
340
+ * {@link getRaffleDrawRun} result, or surfaced by `has_unclaimed_prize`
341
+ * on a {@link getRaffleDrawRunsHistory} row that the consumer drills
342
+ * into).
124
343
  *
344
+ * On success (`errorCode === 0`), the server records the claim and
345
+ * triggers prize delivery through the operator's integration —
346
+ * delivery is server-side, not part of this response.
125
347
  *
126
- * **Example**:
127
- *
128
- * ```javascript
129
- * _smartico.api.claimRafflePrize({won_id:251}).then((result) => {
130
- * console.log(result);
131
- * });
132
- * ```
348
+ * @remarks
349
+ * **Result shape note**: this method returns
350
+ * `TransformedRaffleClaimPrizeResponse` with `errorCode` /
351
+ * `errorMessage` (camelCase full-word) — different from most other
352
+ * SDK result types which use `err_code` / `err_message` (snake_case
353
+ * short-word). Branch on the camelCase keys when reading this
354
+ * method's result.
355
+ *
356
+ * **Preconditions**
357
+ * Pass a `won_id` that identifies an unclaimed winning row for the
358
+ * current user. The `won_id` comes from
359
+ * `TRafflePrizeWinner.raf_won_id` returned by
360
+ * {@link getRaffleDrawRun}.
361
+ *
362
+ * **Error codes** (in `errorCode`)
363
+ * - `0` — success; the claim is recorded and prize delivery is
364
+ * queued server-side.
365
+ * - `1` — generic claim failure. The `errorMessage` distinguishes
366
+ * the specific cause (the server uses one error code for several
367
+ * distinct conditions): the prize has already been claimed, the
368
+ * `won_id` doesn't match a winning row for this user, or the user
369
+ * is in a control group for this raffle. Treat `1` as a retryable
370
+ * error if the message suggests a transient condition; treat as
371
+ * idempotent success if the message indicates already-claimed
372
+ * (the underlying state is what the consumer wants either way —
373
+ * the prize is claimed).
374
+ * - other non-zero — generic server error. Surface `errorMessage`
375
+ * if any.
376
+ *
377
+ * **Claim window**
378
+ * There is no server-enforced claim deadline. Won prizes remain
379
+ * claimable indefinitely until the operator archives them.
380
+ *
381
+ * **Idempotency**: NOT idempotent. A second call on the same
382
+ * `won_id` returns `errorCode === 1` with `errorMessage` indicating
383
+ * the prize has already been claimed. The SDK does NOT enforce an
384
+ * in-flight lock. Guard the call site against double-clicks (set
385
+ * a local "claiming" flag on click, clear it on response).
386
+ *
387
+ * **Refresh after success (and after failure)**
388
+ * The SDK automatically refreshes the raffles cache on every
389
+ * response — both success and failure paths fire the `onUpdate`
390
+ * callback registered via {@link getRaffles}. After `errorCode === 0`,
391
+ * the affected `TRaffleDrawRun.has_unclaimed_prize` (in history)
392
+ * and the winner row's `claimed_date` reflect the claim on the next
393
+ * refresh.
133
394
  *
134
- * **Example in the Visitor mode**:
135
- *
136
- * ```javascript
137
- * _smartico.vapi('EN').claimRafflePrize({ won_id: 251 }).then((result) => {
138
- * console.log(result);
395
+ * **Side effects** (on `errorCode === 0`)
396
+ * - The winner row's `claimed_date` is set server-side.
397
+ * - Prize delivery is queued for the operator's integration to
398
+ * process. Balance / bonus / inbox updates that result from the
399
+ * delivery arrive through their own channels — not in this
400
+ * response.
401
+ *
402
+ * **Throws**
403
+ * `won_id` is required — the SDK throws synchronously when missing
404
+ * or falsy.
405
+ *
406
+ * **UI guidance**: see [UI Guide — `claimRafflePrize`](../../docs/ui/raffles/UIGuide_claimRafflePrize.md).
407
+ *
408
+ * **Visitor mode**: not meaningfully supported. The SDK does not
409
+ * block the call, but visitor sessions have no win history and the
410
+ * server will reject it.
411
+ *
412
+ * @param props.won_id The winning row's `raf_won_id` (from
413
+ * `TRafflePrizeWinner` returned by
414
+ * {@link getRaffleDrawRun}).
415
+ * @returns `{ errorCode, errorMessage? }`; success when
416
+ * `errorCode === 0`. Note camelCase keys (see "Result
417
+ * shape note" above).
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const detail = await window._smartico.api.getRaffleDrawRun({
422
+ * raffle_id: raffleId,
423
+ * run_id: runId,
139
424
  * });
140
- * ```
425
+ * const myWin = detail.prizes.flatMap(p => p.winners).find(w => /* user match here *\/ true);
426
+ *
427
+ * if (!myWin || !myWin.raf_won_id || myWin.claimed_date) {
428
+ * console.log('[smartico] nothing to claim — keep CTA hidden');
429
+ * return;
430
+ * }
141
431
  *
432
+ * console.log('[smartico] claim starting — set in-flight flag, show loading dots on the Claim button, keep the modal open');
433
+ * const r = await window._smartico.api.claimRafflePrize({ won_id: myWin.raf_won_id });
434
+ * console.log('[smartico] claim response received — clear in-flight flag');
435
+ *
436
+ * if (r.errorCode === 0) {
437
+ * console.log('[smartico] claim succeeded — show a success toast; getRaffles onUpdate above will fire with refreshed state; prize delivery happens server-side');
438
+ * } else if (r.errorCode === 1 && r.errorMessage?.toLowerCase().includes('already claimed')) {
439
+ * console.log('[smartico] prize was already claimed (perhaps from another tab) — treat as success, hide the Claim CTA');
440
+ * } else {
441
+ * console.error('[smartico] claim failed — surface this error message to the user and allow retry:', r.errorMessage);
442
+ * }
443
+ * ```
142
444
  */
143
445
  public async claimRafflePrize(props: { won_id: number }): Promise<TransformedRaffleClaimPrizeResponse> {
144
446
  if (!props.won_id) {
@@ -150,9 +452,104 @@ export class WSAPIRaffles extends WSAPIJackpots {
150
452
  }
151
453
 
152
454
  /**
153
- * Requests an opt-in for the specified raffle. Returns the err_code.
455
+ * Opts the current user into a specific raffle draw run. Required
456
+ * for draws where `TRaffleDraw.requires_optin === true` — without
457
+ * opt-in, the user's tickets do NOT participate in that run, even
458
+ * if they hold tickets for the raffle.
459
+ *
460
+ * Opt-in is per-run: a recurring draw's next run requires a fresh
461
+ * opt-in. The user's `TRaffleDraw.user_opted_in` flag reflects the
462
+ * current state for the current run only.
463
+ *
464
+ * @remarks
465
+ * **Preconditions**
466
+ * Read the candidate draw from {@link getRaffles}'s embedded
467
+ * `draws[]` and gate the call on
468
+ * `requires_optin === true && !user_opted_in && is_active &&
469
+ * current_state !== Executed`. Calling without these guards may
470
+ * return a non-zero `err_code`.
471
+ *
472
+ * **Argument mapping** — the three IDs come from different fields:
473
+ * - `raffle_id` — the parent raffle's `TRaffle.id`
474
+ * - `draw_id` — `TRaffleDraw.id` (schedule_id, stable across runs)
475
+ * - `raffle_run_id` — `TRaffleDraw.run_id` (instance ID for this
476
+ * specific run)
477
+ *
478
+ * **Error codes** (in `err_code`)
479
+ * - `0` — success; the user is opted into this run. Tickets
480
+ * collected after the run's `ticket_start_ts` will participate.
481
+ * - `1` — generic opt-in failure. The `err_message` distinguishes
482
+ * the specific cause: the draw doesn't require opt-in
483
+ * (`requires_optin === false`), `raffle_id` doesn't match the
484
+ * `draw_id`, the user is already opted in (or the draw has
485
+ * completed), or the user is in a control group for this raffle.
486
+ * - other non-zero — generic server error. Surface `err_message`.
487
+ *
488
+ * **Idempotency**: NOT idempotent. A second call on the same
489
+ * `raffle_run_id` returns `err_code === 1` with `err_message`
490
+ * indicating the user is already opted in. Treat as success in
491
+ * the UI — the underlying state is what the consumer wants.
492
+ * Guard the call site against double-clicks.
154
493
  *
155
- * **Visitor mode: not supported**
494
+ * **Refresh after success (and after failure)**
495
+ * The SDK automatically refreshes the raffles cache on every
496
+ * response and fires the `onUpdate` callback registered via
497
+ * {@link getRaffles}. After `err_code === 0`, the affected draw's
498
+ * `user_opted_in` flips to `true` on the refreshed list.
499
+ *
500
+ * **Side effects** (on `err_code === 0`)
501
+ * - The user is registered for this run. Tickets earned within
502
+ * the run's eligibility window will participate in the draw.
503
+ * - No balance change. No CRM-side rewards. Opt-in is a metadata
504
+ * operation only.
505
+ *
506
+ * **Throws**
507
+ * `raffle_id`, `draw_id`, and `raffle_run_id` are all required —
508
+ * the SDK throws synchronously when any is missing or falsy.
509
+ *
510
+ * **UI guidance**: see [UI Guide — `requestRaffleOptin`](../../docs/ui/raffles/UIGuide_requestRaffleOptin.md).
511
+ *
512
+ * **Visitor mode**: not supported.
513
+ *
514
+ * @param props.raffle_id The parent raffle's `id`.
515
+ * @param props.draw_id The draw's schedule_id (`TRaffleDraw.id`).
516
+ * @param props.raffle_run_id The run instance ID (`TRaffleDraw.run_id`).
517
+ * @returns `{ err_code, err_message? }`; success
518
+ * when `err_code === 0` (treat
519
+ * "already opted in" as idempotent
520
+ * success).
521
+ *
522
+ * @example
523
+ * ```ts
524
+ * const raffles = await window._smartico.api.getRaffles({
525
+ * onUpdate: (refreshed) => console.log('[smartico] raffles refreshed — re-render', refreshed),
526
+ * });
527
+ * const raffle = raffles[0];
528
+ * const draw = raffle.draws.find(d =>
529
+ * d.requires_optin && !d.user_opted_in && d.is_active && d.current_state !== 3
530
+ * );
531
+ *
532
+ * if (!draw) {
533
+ * console.log('[smartico] no opt-in-required draw available — keep CTA hidden');
534
+ * return;
535
+ * }
536
+ *
537
+ * console.log('[smartico] opt-in starting — set in-flight flag, show loading dots on the Opt-in button');
538
+ * const r = await window._smartico.api.requestRaffleOptin({
539
+ * raffle_id: raffle.id,
540
+ * draw_id: draw.id, // schedule_id, NOT run_id
541
+ * raffle_run_id: draw.run_id,
542
+ * });
543
+ * console.log('[smartico] opt-in response received — clear in-flight flag');
544
+ *
545
+ * if (r.err_code === 0) {
546
+ * console.log('[smartico] opted in successfully — show "Fully opted in" state on the draw card; onUpdate above will fire with user_opted_in: true');
547
+ * } else if (r.err_code === 1 && r.err_message?.toLowerCase().includes('already opted in')) {
548
+ * console.log('[smartico] already opted in (perhaps from another tab) — treat as success, show "Fully opted in"');
549
+ * } else {
550
+ * console.error('[smartico] opt-in failed — surface this error to the user:', r.err_message);
551
+ * }
552
+ * ```
156
553
  */
157
554
  public async requestRaffleOptin(props: { raffle_id: number; draw_id: number; raffle_run_id: number }): Promise<TRaffleOptinResponse> {
158
555
  if (!props.raffle_id) {
@@ -172,4 +569,135 @@ export class WSAPIRaffles extends WSAPIJackpots {
172
569
  err_message: r.errMsg,
173
570
  };
174
571
  }
572
+
573
+ /**
574
+ * Returns every prize the current user has won within a single raffle —
575
+ * across ALL of that raffle's draws, newest-won first — in one paginated
576
+ * call. Use this to power a "my prizes" screen for a raffle (prize name,
577
+ * prize image, the user's name/avatar) without walking
578
+ * {@link getRaffleDrawRunsHistory} and then paging
579
+ * {@link getRaffleDrawRun}'s per-draw winner lists.
580
+ *
581
+ * Each row carries its own `raf_won_id`, which IS the `won_id` to pass to
582
+ * {@link claimRafflePrize}: a row with `requires_claim === true` and no
583
+ * `claimed_date` is directly claimable.
584
+ *
585
+ * @remarks
586
+ * **Authentication required**
587
+ * Works only for an identified (logged-in) user. Visitor / anonymous
588
+ * sessions are rejected — call this only after identify.
589
+ *
590
+ * **Preconditions**
591
+ * `raffle_id` is required — the SDK throws synchronously when it is
592
+ * missing or falsy.
593
+ *
594
+ * **Coverage & sort order**
595
+ * Includes the user's wins from every draw of the raffle — recurring,
596
+ * one-shot, and grand draws, across all historical runs. Rows are ordered
597
+ * newest-win first; there is no "unclaimed first" ordering, so sort
598
+ * client-side if you want claimable prizes at the top.
599
+ *
600
+ * **Pagination**
601
+ * `offset` / `limit` page the `won_prizes[]` rows (the SDK defaults to
602
+ * `0` / `20`). `total` is the authoritative full count of the user's wins
603
+ * for this raffle across all draws — drive "load more" from it
604
+ * (`offset + won_prizes.length < total`). An `offset` past the end returns
605
+ * an empty `won_prizes[]` with the real `total` and `errCode 0` — not an
606
+ * error. The server does NOT clamp `limit`, so always pass an explicit,
607
+ * sane page size.
608
+ *
609
+ * **Rate limit**
610
+ * The server caps this at roughly 30 calls per minute with a ~5-second
611
+ * minimum gap between calls. Fetch on screen open and on explicit "load
612
+ * more" — don't poll it on a timer.
613
+ *
614
+ * **Error codes** (in `errCode`)
615
+ * - `0` — success. Also returned with an empty `won_prizes[]` and
616
+ * `total 0` when the user has no wins, or is not eligible to see this
617
+ * raffle.
618
+ * - `1` — generic server error; surface `errMsg` if present.
619
+ *
620
+ * There are no granular codes — an unknown raffle, an ineligible user,
621
+ * and "no wins" all surface as `errCode 0` with an empty list.
622
+ *
623
+ * **Reading the result**
624
+ * - Null-check `user` before reading it — it is `null` whenever
625
+ * `won_prizes` is empty.
626
+ * - For the avatar, use `user.avatar_id` (already a full URL for a system
627
+ * avatar, otherwise an avatar token to resolve against the widget's
628
+ * avatar domain); `user.avatar_url` is always `null`.
629
+ * - Render `public_username` as-is (it is server-masked for privacy, e.g.
630
+ * `"32:r*****"`) and substitute a "You" label for the current user.
631
+ * - Treat `claimed_date` as the claim flag: `null` until claimed, then
632
+ * epoch ms.
633
+ *
634
+ * **Idempotency / Side effects**: safe and read-only — one-shot promise,
635
+ * no client cache, no subscription. The server caches the response
636
+ * briefly; a successful {@link claimRafflePrize} invalidates that cache,
637
+ * so a follow-up call reflects the new `claimed_date`. This method does
638
+ * NOT refresh the {@link getRaffles} list or fire its `onUpdate` — re-call
639
+ * manually to pick up newly-won prizes or a `claimed_date` flip.
640
+ *
641
+ * **UI guidance**: see [UI Guide — `getRaffleWonPrizes`](../../docs/ui/raffles/UIGuide_getRaffleWonPrizes.md).
642
+ *
643
+ * **Visitor mode**: not supported (see "Authentication required").
644
+ *
645
+ * @param props.raffle_id The parent raffle's `id` (from `TRaffle.id`). Required.
646
+ * @param props.offset Zero-based index of the first row to return. Defaults to `0`.
647
+ * @param props.limit Page size. Defaults to `20`.
648
+ * @returns Promise resolving to {@link GetRaffleWonPrizesResponse}
649
+ * (`user`, this page of `won_prizes`, and `total`;
650
+ * `errCode 0` on success).
651
+ *
652
+ * @example
653
+ * ```ts
654
+ * const raffles = await window._smartico.api.getRaffles();
655
+ * const raffle = raffles[0];
656
+ *
657
+ * // First page of the user's won prizes for this raffle.
658
+ * const page = await window._smartico.api.getRaffleWonPrizes({
659
+ * raffle_id: raffle.id,
660
+ * offset: 0,
661
+ * limit: 20,
662
+ * });
663
+ *
664
+ * if (page.errCode !== 0) {
665
+ * console.error('[smartico] could not load won prizes — show a retry state:', page.errMsg);
666
+ * return;
667
+ * }
668
+ * if (page.won_prizes.length === 0) {
669
+ * console.log('[smartico] no wins in this raffle (or not eligible) — render the empty state');
670
+ * return;
671
+ * }
672
+ *
673
+ * console.log('[smartico]', page.user?.public_username, 'won', page.total, 'prizes total');
674
+ * for (const prize of page.won_prizes) {
675
+ * console.log('[smartico] render prize card —', prize.public_meta.name, prize.public_meta.image_url);
676
+ * if (prize.requires_claim && !prize.claimed_date) {
677
+ * console.log('[smartico] show a Claim CTA — on click call claimRafflePrize({ won_id:', prize.raf_won_id, '})');
678
+ * }
679
+ * }
680
+ *
681
+ * // Load more.
682
+ * if (page.offset + page.won_prizes.length < page.total) {
683
+ * const next = await window._smartico.api.getRaffleWonPrizes({
684
+ * raffle_id: raffle.id,
685
+ * offset: page.offset + page.limit,
686
+ * limit: 20,
687
+ * });
688
+ * console.log('[smartico] appended', next.won_prizes.length, 'more prizes');
689
+ * }
690
+ * ```
691
+ */
692
+ public async getRaffleWonPrizes(props: { raffle_id: number; offset?: number; limit?: number }): Promise<GetRaffleWonPrizesResponse> {
693
+ if (!props.raffle_id) {
694
+ throw new Error('raffle_id is required');
695
+ }
696
+
697
+ return await this.api.getRaffleWonPrizes(this.userExtId, {
698
+ raffle_id: props.raffle_id,
699
+ offset: props.offset ?? 0,
700
+ limit: props.limit ?? 20,
701
+ });
702
+ }
175
703
  }