@hizi.io/engine-sdk 0.1.9

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 (64) hide show
  1. package/README.md +212 -0
  2. package/lib/api.d.ts +198 -0
  3. package/lib/api.js +352 -0
  4. package/lib/constants.d.ts +44 -0
  5. package/lib/constants.js +56 -0
  6. package/lib/index.d.ts +7 -0
  7. package/lib/index.js +37 -0
  8. package/lib/network.d.ts +9 -0
  9. package/lib/network.js +63 -0
  10. package/lib/types/balance.d.ts +20 -0
  11. package/lib/types/balance.js +2 -0
  12. package/lib/types/blackjack.d.ts +163 -0
  13. package/lib/types/blackjack.js +22 -0
  14. package/lib/types/buyFeatureOption.d.ts +11 -0
  15. package/lib/types/buyFeatureOption.js +2 -0
  16. package/lib/types/collectOptions.d.ts +8 -0
  17. package/lib/types/collectOptions.js +2 -0
  18. package/lib/types/crash.d.ts +223 -0
  19. package/lib/types/crash.js +80 -0
  20. package/lib/types/freePlayInfo.d.ts +11 -0
  21. package/lib/types/freePlayInfo.js +2 -0
  22. package/lib/types/gameResult.d.ts +48 -0
  23. package/lib/types/gameResult.js +2 -0
  24. package/lib/types/gameRoundInfo.d.ts +19 -0
  25. package/lib/types/gameRoundInfo.js +2 -0
  26. package/lib/types/gameSettings.d.ts +133 -0
  27. package/lib/types/gameSettings.js +16 -0
  28. package/lib/types/gameState.d.ts +20 -0
  29. package/lib/types/gameState.js +2 -0
  30. package/lib/types/index.d.ts +32 -0
  31. package/lib/types/index.js +22 -0
  32. package/lib/types/keno.d.ts +34 -0
  33. package/lib/types/keno.js +18 -0
  34. package/lib/types/loadConfigConfig.d.ts +42 -0
  35. package/lib/types/loadConfigConfig.js +2 -0
  36. package/lib/types/loginOptions.d.ts +7 -0
  37. package/lib/types/loginOptions.js +2 -0
  38. package/lib/types/mines.d.ts +26 -0
  39. package/lib/types/mines.js +19 -0
  40. package/lib/types/network.d.ts +24 -0
  41. package/lib/types/network.js +2 -0
  42. package/lib/types/pfVerifyOptions.d.ts +48 -0
  43. package/lib/types/pfVerifyOptions.js +2 -0
  44. package/lib/types/placeBetOptions.d.ts +16 -0
  45. package/lib/types/placeBetOptions.js +2 -0
  46. package/lib/types/progressionCounter.d.ts +65 -0
  47. package/lib/types/progressionCounter.js +2 -0
  48. package/lib/types/replies.d.ts +107 -0
  49. package/lib/types/replies.js +2 -0
  50. package/lib/types/roulette.d.ts +53 -0
  51. package/lib/types/roulette.js +11 -0
  52. package/lib/types/scenarioInfo.d.ts +12 -0
  53. package/lib/types/scenarioInfo.js +2 -0
  54. package/lib/types/sessionOptions.d.ts +7 -0
  55. package/lib/types/sessionOptions.js +2 -0
  56. package/lib/types/spinAward.d.ts +31 -0
  57. package/lib/types/spinAward.js +12 -0
  58. package/lib/types/spinInfo.d.ts +9 -0
  59. package/lib/types/spinInfo.js +2 -0
  60. package/lib/types/tokenData.d.ts +7 -0
  61. package/lib/types/tokenData.js +2 -0
  62. package/lib/websocket.d.ts +27 -0
  63. package/lib/websocket.js +186 -0
  64. package/package.json +19 -0
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # @hizi.io/engine-sdk
2
+
3
+ Type-safe SDK for game frontends to communicate with the [hizi engine](https://code.hoelle.games/hizi/hizi-engine). Provides helper functions for login, configuration loading, bet placement, and win collection via the Hizi RGS platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @hizi.io/engine-sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { login, loadConfig, placeBet, collect } from '@hizi.io/engine-sdk';
15
+
16
+ // 1. Login — exchange launch token for session token
17
+ const params = new URLSearchParams(window.location.search);
18
+ const loginResponse = await login({
19
+ loginURL: params.get('login'),
20
+ launchToken: params.get('token'),
21
+ });
22
+ const { token, backendURL } = loginResponse.result;
23
+
24
+ // 2. Load game configuration
25
+ const configResponse = await loadConfig({ backendURL, token });
26
+ const config = configResponse.result.config;
27
+
28
+ // 3. Place a bet
29
+ const betResponse = await placeBet({ backendURL, token, stake: config.stakes[0] });
30
+ const gameResult = betResponse.result.result;
31
+
32
+ console.log('Scenario:', gameResult.scenario); // your game-specific data
33
+ console.log('Win:', gameResult.totalWin); // win multiplier
34
+
35
+ // 4. Handle multi-step rounds
36
+ while (gameResult.engineData.inProgress) {
37
+ const next = await placeBet({ backendURL, token });
38
+ gameResult = next.result.result;
39
+ }
40
+
41
+ // 5. Collect winnings (only for games with wager features)
42
+ if (config.wagerFeatures?.length) {
43
+ await collect({ backendURL, token });
44
+ }
45
+ ```
46
+
47
+ ## How It Works
48
+
49
+ ```
50
+ Game Frontend ↔ HTTP/WebSocket ↔ Hizi RGS ↔ hizi engine ↔ .db file
51
+ ```
52
+
53
+ The backend handles outcome selection, balance management, authentication, and game state. Your frontend makes API calls and renders results.
54
+
55
+ ## Endpoints
56
+
57
+ | Function | Description |
58
+ | ------------------------------------------- | -------------------------------------------- |
59
+ | `login({ loginURL, launchToken })` | Exchange launch token for a session token |
60
+ | `loadConfig({ backendURL, token })` | Get game config (stakes, RTP, buy-features) |
61
+ | `placeBet({ backendURL, token, stake? })` | Place a bet or continue a multi-step round |
62
+ | `collect({ backendURL, token, amount? })` | Collect winnings after a round completes |
63
+ | `refresh(refreshURL)` | Refresh the session token |
64
+ | `reportAnimationEnd({ backendURL, token })` | Notify backend that animation finished |
65
+ | `updateBalance({ backendURL, token })` | Request an updated balance |
66
+ | `enableWebSockets(webSocketURL)` | Enable WebSocket transport for lower latency |
67
+
68
+ ## Game Flow
69
+
70
+ ### 1. Login
71
+
72
+ Games are launched with URL parameters containing a login URL and short-lived token:
73
+
74
+ ```typescript
75
+ const loginURL = new URLSearchParams(window.location.search).get('login');
76
+ const launchToken = new URLSearchParams(window.location.search).get('token');
77
+ const response = await login({ loginURL, launchToken });
78
+ const { token, backendURL } = response.result;
79
+ ```
80
+
81
+ ### 2. Load Configuration
82
+
83
+ ```typescript
84
+ const response = await loadConfig({ backendURL, token });
85
+ const config = response.result.config;
86
+ // config.stakes — available stake amounts
87
+ // config.rtp — return to player percentage
88
+ // config.buyFeatures — available buy-feature options
89
+ // config.wagerFeatures — available wager features (if any)
90
+ ```
91
+
92
+ ### 3. Place a Bet
93
+
94
+ ```typescript
95
+ const response = await placeBet({ backendURL, token, stake: stakeAmount });
96
+ const gameResult = response.result.result;
97
+ ```
98
+
99
+ ### 4. Handle Multi-step Rounds
100
+
101
+ If `engineData.inProgress` is `true`, the round isn't complete. Keep calling `placeBet` to continue:
102
+
103
+ ```typescript
104
+ if (gameResult.engineData.inProgress) {
105
+ const next = await placeBet({ backendURL, token });
106
+ }
107
+ ```
108
+
109
+ This happens for multi-result scenarios, free spins, and bonus features.
110
+
111
+ ### 5. Player Choices
112
+
113
+ When `engineData.playerChoice` is set, present options to the player and send the selection:
114
+
115
+ ```typescript
116
+ if (gameResult.engineData.playerChoice) {
117
+ const chosenIndex = await presentChoiceUI(gameResult.engineData.playerChoice);
118
+ await placeBet({
119
+ backendURL,
120
+ token,
121
+ playerChoiceIndex: chosenIndex,
122
+ });
123
+ }
124
+ ```
125
+
126
+ ### 6. Buy-Features
127
+
128
+ Purchase direct entry into a bonus feature:
129
+
130
+ ```typescript
131
+ const feature = config.buyFeatures[0];
132
+ await placeBet({
133
+ backendURL,
134
+ token,
135
+ stake: currentStake,
136
+ featureToBuy: feature.id,
137
+ });
138
+ ```
139
+
140
+ ### 7. Collect or Continue Wager
141
+
142
+ Games **without** wager features auto-end rounds and credit winnings. Games **with** wager features keep the round open so the player can collect or continue wagering:
143
+
144
+ ```typescript
145
+ // Collect winnings
146
+ await collect({ backendURL, token });
147
+
148
+ // Or continue wagering (engine handles wager features via placeBet continuation)
149
+ await placeBet({ backendURL, token });
150
+ ```
151
+
152
+ ## Error Handling
153
+
154
+ All functions return `TNetworkResponse<T>` — always check `success`:
155
+
156
+ ```typescript
157
+ const response = await placeBet({ backendURL, token, stake });
158
+
159
+ if (!response.success) {
160
+ if (recoverableErrorCodes.includes(response.error.code)) {
161
+ // Retry-able: balance too low, rate limit, network error
162
+ } else {
163
+ // Fatal: refresh the game
164
+ }
165
+ return;
166
+ }
167
+
168
+ const gameResult = response.result.result;
169
+ ```
170
+
171
+ ## WebSocket Support
172
+
173
+ Enable WebSocket transport for lower latency — all subsequent calls automatically route through it:
174
+
175
+ ```typescript
176
+ import { enableWebSockets } from '@hizi.io/engine-sdk';
177
+ const wsHandler = await enableWebSockets(webSocketURL);
178
+ ```
179
+
180
+ ## Key Types
181
+
182
+ ```typescript
183
+ import type {
184
+ IGameResult, // Game result with scenario data and engine state
185
+ ILoadConfigConfig, // Game configuration (stakes, RTP, buy-features)
186
+ IScenarioInfo, // Multi-result scenario progression
187
+ ISpinInfo, // Free spin / bonus feature tracking
188
+ IBuyFeatureOption, // Buy-feature definition
189
+ IPlaceBetReply, // placeBet response
190
+ ICollectReply, // collect response
191
+ ILoadConfigReply, // loadConfig response
192
+ IConnectReply, // login/refresh response
193
+ TNetworkResponse, // Success | Error wrapper
194
+ IGameSettings, // Platform game settings
195
+ IGameRoundInfo, // Round status
196
+ IFreePlayInfo, // Free play info
197
+ WebSocketHandler, // WebSocket controller
198
+ ISessionOptions, // Common { backendURL, token } options
199
+ ILoginOptions, // login() options
200
+ IPlaceBetOptions, // placeBet() options
201
+ ICollectOptions, // collect() options
202
+ } from '@hizi.io/engine-sdk';
203
+ ```
204
+
205
+ ## Related Projects
206
+
207
+ | Repo | Description |
208
+ | ------------------------------------------------------------------ | -------------------------------- |
209
+ | [hizi-engine](https://code.hoelle.games/hizi/hizi-engine) | Runtime server |
210
+ | [hizi-generator-ts](https://code.hoelle.games/hizi/hizi-generator-ts) | .db file generation (TypeScript) |
211
+ | [hizi-engine-tester](https://code.hoelle.games/hizi/hizi-engine-tester) | Web-based testing UI |
212
+ | [hizi-engine-docs](https://code.hoelle.games/hizi/hizi-engine-docs) | Full documentation |
package/lib/api.d.ts ADDED
@@ -0,0 +1,198 @@
1
+ import type { TNetworkResponse, IConnectReply, ILoadConfigReply, IPlaceBetReply, ICollectReply, IBalanceReply, IFreePlayInfo, IPfVerifyReply, ISessionOptions, ILoginOptions, IPlaceBetOptions, ICollectOptions, IPfVerifyOptions } from './types/index.js';
2
+ /**
3
+ * Exchange a launch token for a session token.
4
+ *
5
+ * The `loginURL` and `launchToken` are provided as URL query parameters
6
+ * when the game is launched by the operator.
7
+ *
8
+ * @param options - Login credentials from the launch URL.
9
+ * @param options.loginURL - The operator-provided login endpoint URL.
10
+ * @param options.launchToken - Short-lived token from the launch URL query string.
11
+ * @returns A session token, backend URL, and platform settings on success.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const response = await login({ loginURL, launchToken });
16
+ * if (response.success) {
17
+ * const { token, backendURL } = response.result;
18
+ * }
19
+ * ```
20
+ */
21
+ export declare function login(options: ILoginOptions): Promise<TNetworkResponse<IConnectReply>>;
22
+ /**
23
+ * Load the game configuration including available stakes, RTP, and buy features.
24
+ *
25
+ * Call this once after {@link login} to retrieve the game's configuration before
26
+ * placing any bets. If a previous round was interrupted, the response includes
27
+ * `gameResult` and `amountToCollect` for resumption.
28
+ *
29
+ * @param options - Session credentials from the login response.
30
+ * @param options.backendURL - Backend URL from the login response.
31
+ * @param options.token - Session token.
32
+ * @returns Game configuration, balance, and any in-progress round data.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const response = await loadConfig({ backendURL, token });
37
+ * if (response.success) {
38
+ * const { stakes, rtp, buyFeatures } = response.result.config;
39
+ * }
40
+ * ```
41
+ */
42
+ export declare function loadConfig(options: ISessionOptions): Promise<TNetworkResponse<ILoadConfigReply>>;
43
+ /**
44
+ * Place a bet and receive a game result, or continue an in-progress round.
45
+ *
46
+ * - **New spin** — pass the desired `stake` amount.
47
+ * - **Continue round** — omit `stake` when `engineData.inProgress` is `true`.
48
+ * - **Buy feature** — pass `featureToBuy` to enter a bonus directly (engine computes the price).
49
+ * - **Player choice** — pass `playerChoiceIndex` when `engineData.playerChoice` is set.
50
+ *
51
+ * @param options - Bet parameters.
52
+ * @param options.backendURL - Backend URL from the login response.
53
+ * @param options.token - Session token.
54
+ * @param options.stake - Stake amount in minor currency units. Required for the first call of a game round.
55
+ * @param options.featureToBuy - Buy-feature ID (e.g. `'freespin'`).
56
+ * @param options.playerChoiceIndex - Index of the selected option when `engineData.playerChoice` is set.
57
+ * @param options.useTicket - Set `true` to consume a free play ticket.
58
+ * @param options.useTicketFeatureType - Feature type of the free play ticket.
59
+ * @param options.additionalData - Additional game-specific parameters.
60
+ * @returns The game result including scenario data, engine state, and cumulative win.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // New spin
65
+ * const response = await placeBet({ backendURL, token, stake });
66
+ *
67
+ * // Buy feature
68
+ * const response = await placeBet({ backendURL, token, stake, featureToBuy: 'freespin' });
69
+ *
70
+ * // Continue round
71
+ * const response = await placeBet({ backendURL, token });
72
+ * ```
73
+ */
74
+ export declare function placeBet(options: IPlaceBetOptions): Promise<TNetworkResponse<IPlaceBetReply>>;
75
+ /**
76
+ * Collect winnings after a completed round.
77
+ *
78
+ * Only available for games with wager features (`config.wagerFeatures` is present).
79
+ * Games without wager features auto-end the round and credit winnings automatically.
80
+ *
81
+ * @param options - Session credentials and optional partial amount.
82
+ * @param options.backendURL - Backend URL from the login response.
83
+ * @param options.token - Session token.
84
+ * @param options.amount - Amount to collect. Omit to collect the full available amount.
85
+ * @returns The credited amount and updated balance.
86
+ * @throws When called on a game without wager features, or when no winnings are available.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * if (gameResult.engineData.canCollect) {
91
+ * const response = await collect({ backendURL, token });
92
+ * }
93
+ * ```
94
+ */
95
+ export declare function collect(options: ICollectOptions): Promise<TNetworkResponse<ICollectReply>>;
96
+ /**
97
+ * Re-run a past round against its revealed PF seeds and get back the
98
+ * engine's offline replay — the per-call RNG audit (`rngData`) and the
99
+ * per-step game outcomes (`steps`) — so the caller can diff them against
100
+ * what they recorded live.
101
+ *
102
+ * Only meaningful for rounds played with `config.rng === 'pf'`. The
103
+ * endpoint never touches the wallet, progression counters, or operator
104
+ * caps; it's pure compute.
105
+ *
106
+ * Two checks make up a passing verification:
107
+ *
108
+ * 1. **Audit replay** — `reply.rngData` matches the live `pf.rngData`
109
+ * element-wise. A swapped server seed would yield different draws, so
110
+ * this transitively proves the revealed seed is the one committed to.
111
+ * 2. **Result replay** — `reply.steps[i].scenario` / `totalWin` match the
112
+ * live round at each step. The terminal step is `steps[steps.length - 1]`.
113
+ *
114
+ * @param options - Verify parameters; see {@link IPfVerifyOptions}.
115
+ * @param options.backendURL - Backend URL from the login response.
116
+ * @param options.token - Session token (used to resolve the game config).
117
+ * @param options.serverSeed - Revealed server seed from the round's `pf` block.
118
+ * @param options.clientSeed - Client seed bound to the round.
119
+ * @param options.startNonce - Defaults to `0`. Set when the round opened mid-PF-session.
120
+ * @param options.stake - Stake the round opened with (required by games that need it to settle).
121
+ * @param options.featureToBuy - Buy-feature id the round opened on, if any.
122
+ * @param options.initialData - Mirror the round's opening payload (blackjack side bets, …).
123
+ * @param options.bets - Roulette / crash opening bets.
124
+ * @param options.playerNumbers - Keno picks, if the player chose their own.
125
+ * @param options.actions - Continuation actions in order; shape per game (see {@link IPfVerifyAction}).
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * // Verify a one-shot roulette round.
130
+ * const reply = await pfVerify({
131
+ * backendURL, token,
132
+ * serverSeed: pf.revealedServerSeed,
133
+ * clientSeed: pf.clientSeed,
134
+ * stake: 200,
135
+ * bets: [{ type: 'straight', selection: 17, stake: 100 }, { type: 'red', stake: 100 }],
136
+ * });
137
+ * if (reply.success) {
138
+ * const rngOk = deepEqual(reply.result.rngData, pf.rngData);
139
+ * const pocketOk = (reply.result.steps[0].scenario as { pocket: number }).pocket === liveScenario.pocket;
140
+ * }
141
+ * ```
142
+ */
143
+ export declare function pfVerify(options: IPfVerifyOptions): Promise<TNetworkResponse<IPfVerifyReply>>;
144
+ /**
145
+ * Refresh the session token when it expires.
146
+ *
147
+ * Call this when API requests start returning `SESSIONINVALID` or `NOTLOGGEDON`
148
+ * errors. The new session token and URLs are returned in the response.
149
+ *
150
+ * @param refreshURL - The refresh endpoint URL from the {@link login} response (`result.refreshURL`).
151
+ * @returns A new session token and updated platform info.
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * const response = await refresh(refreshURL);
156
+ * if (response.success) {
157
+ * token = response.result.token;
158
+ * }
159
+ * ```
160
+ */
161
+ export declare function refresh(refreshURL: string): Promise<TNetworkResponse<IConnectReply>>;
162
+ /**
163
+ * Report that the game animation has finished playing.
164
+ *
165
+ * Only needed when `gameSettings.reportAnimationEnd` is `true` (set by the operator).
166
+ * Call this after your spin/win animation completes.
167
+ *
168
+ * @param options - Session credentials.
169
+ * @param options.backendURL - Backend URL from the login response.
170
+ * @param options.token - Session token.
171
+ */
172
+ export declare function reportAnimationEnd(options: ISessionOptions): Promise<TNetworkResponse<void>>;
173
+ /**
174
+ * Request an updated balance from the server.
175
+ *
176
+ * Use this to refresh the displayed balance outside of the normal
177
+ * `placeBet`/`collect` flow (e.g. after an external deposit).
178
+ *
179
+ * @param options - Session credentials.
180
+ * @param options.backendURL - Backend URL from the login response.
181
+ * @param options.token - Session token.
182
+ * @returns The player's current balance.
183
+ */
184
+ export declare function updateBalance(options: ISessionOptions): Promise<TNetworkResponse<IBalanceReply>>;
185
+ /**
186
+ * Get the total number of free plays remaining.
187
+ *
188
+ * @param freePlaysAvailable - The `freePlaysAvailable` array from a `loadConfig` or `placeBet` response.
189
+ * @returns Total free play count across all entries, or `0` if none available.
190
+ */
191
+ export declare function getFreePlaysRemaining(freePlaysAvailable?: IFreePlayInfo[]): number;
192
+ /**
193
+ * Get the stake amount for available free plays.
194
+ *
195
+ * @param freePlaysAvailable - The `freePlaysAvailable` array from a `loadConfig` or `placeBet` response.
196
+ * @returns The first free play's stake amount, or `undefined` if none available.
197
+ */
198
+ export declare function getFreePlayStake(freePlaysAvailable?: IFreePlayInfo[]): number | undefined;