@hyve-sdk/js 1.1.2 → 1.3.1-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,130 @@
1
1
  // src/utils/index.ts
2
- import { ethers } from "ethers";
3
2
  import { v4 as uuidv4 } from "uuid";
3
+
4
+ // src/utils/logger.ts
5
+ var Logger = class _Logger {
6
+ config;
7
+ constructor() {
8
+ this.config = this.initializeConfig();
9
+ }
10
+ /**
11
+ * Initialize logger configuration based on NODE_ENV
12
+ */
13
+ initializeConfig() {
14
+ const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
15
+ let enabled = false;
16
+ let levels = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
17
+ if (isNode) {
18
+ const nodeEnv = process.env.NODE_ENV;
19
+ enabled = nodeEnv !== "production";
20
+ const logLevelEnv = process.env.HYVE_SDK_LOG_LEVEL;
21
+ if (logLevelEnv) {
22
+ const configuredLevels = logLevelEnv.split(",").map((l) => l.trim());
23
+ levels = new Set(configuredLevels);
24
+ }
25
+ } else if (typeof window !== "undefined") {
26
+ try {
27
+ enabled = process.env.NODE_ENV !== "production";
28
+ } catch (e) {
29
+ enabled = true;
30
+ }
31
+ try {
32
+ const localStorageLogLevel = localStorage.getItem("HYVE_SDK_LOG_LEVEL");
33
+ if (localStorageLogLevel) {
34
+ const configuredLevels = localStorageLogLevel.split(",").map((l) => l.trim());
35
+ levels = new Set(configuredLevels);
36
+ }
37
+ } catch (e) {
38
+ }
39
+ }
40
+ return {
41
+ enabled,
42
+ prefix: "[Hyve SDK]",
43
+ levels
44
+ };
45
+ }
46
+ /**
47
+ * Set which log levels to display
48
+ */
49
+ setLevels(levels) {
50
+ this.config.levels = new Set(levels);
51
+ if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
52
+ try {
53
+ localStorage.setItem("HYVE_SDK_LOG_LEVEL", levels.join(","));
54
+ } catch (e) {
55
+ }
56
+ }
57
+ }
58
+ /**
59
+ * Check if logging is enabled
60
+ */
61
+ isEnabled() {
62
+ return this.config.enabled;
63
+ }
64
+ /**
65
+ * Internal log method
66
+ */
67
+ log(level, ...args) {
68
+ if (!this.config.enabled || !this.config.levels.has(level)) {
69
+ return;
70
+ }
71
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
72
+ const prefix = `${this.config.prefix} [${level.toUpperCase()}] [${timestamp}]`;
73
+ switch (level) {
74
+ case "debug":
75
+ console.debug(prefix, ...args);
76
+ break;
77
+ case "info":
78
+ console.info(prefix, ...args);
79
+ break;
80
+ case "warn":
81
+ console.warn(prefix, ...args);
82
+ break;
83
+ case "error":
84
+ console.error(prefix, ...args);
85
+ break;
86
+ }
87
+ }
88
+ /**
89
+ * Log a debug message
90
+ */
91
+ debug(...args) {
92
+ this.log("debug", ...args);
93
+ }
94
+ /**
95
+ * Log an info message
96
+ */
97
+ info(...args) {
98
+ this.log("info", ...args);
99
+ }
100
+ /**
101
+ * Log a warning message
102
+ */
103
+ warn(...args) {
104
+ this.log("warn", ...args);
105
+ }
106
+ /**
107
+ * Log an error message
108
+ */
109
+ error(...args) {
110
+ this.log("error", ...args);
111
+ }
112
+ /**
113
+ * Create a child logger with a specific prefix
114
+ */
115
+ child(prefix) {
116
+ const childLogger = new _Logger();
117
+ childLogger.config = {
118
+ ...this.config,
119
+ prefix: `${this.config.prefix} [${prefix}]`
120
+ };
121
+ return childLogger;
122
+ }
123
+ };
124
+ var logger = new Logger();
125
+
126
+ // src/utils/auth.ts
127
+ import { ethers } from "ethers";
4
128
  function parseUrlParams(searchParams) {
5
129
  const params = typeof searchParams === "string" ? new URLSearchParams(searchParams) : searchParams;
6
130
  return {
@@ -9,7 +133,8 @@ function parseUrlParams(searchParams) {
9
133
  gameStartTab: params.get("game_start_tab") || "",
10
134
  hyveToken: params.get("hyve-token") || "",
11
135
  platform: params.get("platform") || "",
12
- hyveAccess: params.get("hyve-access") || ""
136
+ hyveAccess: params.get("hyve-access") || "",
137
+ gameId: params.get("game-id") || ""
13
138
  };
14
139
  }
15
140
  function validateSignature(signature, message) {
@@ -17,7 +142,7 @@ function validateSignature(signature, message) {
17
142
  const recoveredAddress = ethers.verifyMessage(message, signature);
18
143
  return !!recoveredAddress;
19
144
  } catch (error) {
20
- console.error("Signature validation error:", error);
145
+ logger.error("Signature validation error:", error);
21
146
  return false;
22
147
  }
23
148
  }
@@ -44,7 +169,7 @@ function handleVerifyMessage(signature, message) {
44
169
  }
45
170
  return userAddress;
46
171
  } catch (error) {
47
- console.error("Error verifying message:", error);
172
+ logger.error("Error verifying message:", error);
48
173
  return false;
49
174
  }
50
175
  }
@@ -52,7 +177,7 @@ function verifyHyveToken(hyveToken, maxAgeSec = 600) {
52
177
  try {
53
178
  const parts = hyveToken.split(".");
54
179
  if (parts.length !== 4) {
55
- console.error(
180
+ logger.error(
56
181
  "Invalid hyve-token format: expected 4 parts, got",
57
182
  parts.length
58
183
  );
@@ -60,30 +185,30 @@ function verifyHyveToken(hyveToken, maxAgeSec = 600) {
60
185
  }
61
186
  const [signature, address, randomBase64, timestampStr] = parts;
62
187
  if (!signature || !address || !randomBase64 || !timestampStr) {
63
- console.error("Missing hyve-token components");
188
+ logger.error("Missing hyve-token components");
64
189
  return false;
65
190
  }
66
191
  const message = `${address}.${randomBase64}.${timestampStr}`;
67
192
  const recoveredAddress = ethers.verifyMessage(message, signature);
68
193
  if (recoveredAddress.toLowerCase() !== address.toLowerCase()) {
69
- console.error("Hyve-token signature verification failed");
194
+ logger.error("Hyve-token signature verification failed");
70
195
  return false;
71
196
  }
72
197
  const timestamp = parseInt(timestampStr, 10);
73
198
  if (!Number.isFinite(timestamp)) {
74
- console.error("Invalid hyve-token timestamp");
199
+ logger.error("Invalid hyve-token timestamp");
75
200
  return false;
76
201
  }
77
202
  const now = Math.floor(Date.now() / 1e3);
78
203
  if (now - timestamp > maxAgeSec) {
79
- console.error(
204
+ logger.error(
80
205
  `Hyve-token expired (age: ${now - timestamp}s, max: ${maxAgeSec}s)`
81
206
  );
82
207
  return false;
83
208
  }
84
209
  return address;
85
210
  } catch (error) {
86
- console.error("Hyve-token verification error:", error);
211
+ logger.error("Hyve-token verification error:", error);
87
212
  return false;
88
213
  }
89
214
  }
@@ -129,11 +254,8 @@ function verifyAuthentication(params, maxAgeSec = 600) {
129
254
  error: "No authentication tokens provided"
130
255
  };
131
256
  }
132
- function generateUUID() {
133
- return uuidv4();
134
- }
135
257
  function isDomainAllowed(allowedDomains, hostname) {
136
- console.log("Hostname", hostname);
258
+ logger.debug("Checking hostname:", hostname);
137
259
  if (!allowedDomains) return true;
138
260
  const targetHostname = hostname || "";
139
261
  if (!targetHostname) return false;
@@ -151,6 +273,216 @@ function isDomainAllowed(allowedDomains, hostname) {
151
273
  });
152
274
  }
153
275
 
276
+ // src/utils/native-bridge.ts
277
+ var NativeMessageType = /* @__PURE__ */ ((NativeMessageType2) => {
278
+ NativeMessageType2["CHECK_IAP_AVAILABILITY"] = "CHECK_IAP_AVAILABILITY";
279
+ NativeMessageType2["REQUEST_NOTIFICATION_PERMISSION"] = "REQUEST_NOTIFICATION_PERMISSION";
280
+ NativeMessageType2["GET_PRODUCTS"] = "GET_PRODUCTS";
281
+ NativeMessageType2["PURCHASE"] = "PURCHASE";
282
+ NativeMessageType2["IAP_AVAILABILITY_RESULT"] = "IAP_AVAILABILITY_RESULT";
283
+ NativeMessageType2["PUSH_PERMISSION_GRANTED"] = "PUSH_PERMISSION_GRANTED";
284
+ NativeMessageType2["PUSH_PERMISSION_DENIED"] = "PUSH_PERMISSION_DENIED";
285
+ NativeMessageType2["PRODUCTS_RESULT"] = "PRODUCTS_RESULT";
286
+ NativeMessageType2["PURCHASE_COMPLETE"] = "PURCHASE_COMPLETE";
287
+ NativeMessageType2["PURCHASE_ERROR"] = "PURCHASE_ERROR";
288
+ return NativeMessageType2;
289
+ })(NativeMessageType || {});
290
+ var NativeBridge = class {
291
+ static handlers = /* @__PURE__ */ new Map();
292
+ static isInitialized = false;
293
+ /**
294
+ * Checks if the app is running inside a React Native WebView
295
+ */
296
+ static isNativeContext() {
297
+ return typeof window !== "undefined" && "ReactNativeWebView" in window;
298
+ }
299
+ /**
300
+ * Initializes the native bridge message listener
301
+ * Call this once when your app starts
302
+ */
303
+ static initialize() {
304
+ if (this.isInitialized) {
305
+ logger.debug("[NativeBridge] Already initialized");
306
+ return;
307
+ }
308
+ if (typeof window === "undefined") {
309
+ logger.warn("[NativeBridge] Window not available, skipping initialization");
310
+ return;
311
+ }
312
+ const boundHandler = this.handleNativeMessage.bind(this);
313
+ window.addEventListener("message", boundHandler);
314
+ document.addEventListener("message", boundHandler);
315
+ this.isInitialized = true;
316
+ logger.info("[NativeBridge] Initialized and listening for native messages");
317
+ }
318
+ /**
319
+ * Handles incoming messages from React Native
320
+ */
321
+ static handleNativeMessage(event) {
322
+ try {
323
+ let data;
324
+ if (typeof event.data === "string") {
325
+ try {
326
+ data = JSON.parse(event.data);
327
+ logger.debug("[NativeBridge] Parsed message string:", data);
328
+ } catch (parseError) {
329
+ logger.debug("[NativeBridge] Failed to parse message, not JSON:", event.data);
330
+ return;
331
+ }
332
+ } else if (typeof event.data === "object" && event.data !== null) {
333
+ data = event.data;
334
+ logger.debug("[NativeBridge] Received message object:", data);
335
+ } else {
336
+ logger.debug("[NativeBridge] Received invalid message type:", typeof event.data);
337
+ return;
338
+ }
339
+ if (!data || !data.type) {
340
+ logger.debug("[NativeBridge] Received message without type, ignoring");
341
+ return;
342
+ }
343
+ const handler = this.handlers.get(data.type);
344
+ if (handler) {
345
+ logger.info(`[NativeBridge] Handling message: ${data.type}`, data.payload);
346
+ handler(data.payload);
347
+ } else {
348
+ logger.warn(`[NativeBridge] No handler registered for: ${data.type}`);
349
+ }
350
+ } catch (error) {
351
+ logger.error("[NativeBridge] Error handling native message:", error);
352
+ }
353
+ }
354
+ /**
355
+ * Sends a message to React Native
356
+ * @param type Message type
357
+ * @param payload Optional payload data
358
+ */
359
+ static send(type, payload) {
360
+ if (!this.isNativeContext()) {
361
+ logger.debug(
362
+ `[NativeBridge] Not in native context, skipping message: ${type}`
363
+ );
364
+ return;
365
+ }
366
+ try {
367
+ const message = {
368
+ type,
369
+ payload,
370
+ timestamp: Date.now()
371
+ };
372
+ window.ReactNativeWebView.postMessage(JSON.stringify(message));
373
+ logger.debug(`[NativeBridge] Sent message to native: ${type}`, payload);
374
+ } catch (error) {
375
+ logger.error(`[NativeBridge] Error sending message to native:`, error);
376
+ }
377
+ }
378
+ /**
379
+ * Registers a handler for messages from React Native
380
+ * @param type Message type to listen for
381
+ * @param handler Function to call when message is received
382
+ */
383
+ static on(type, handler) {
384
+ this.handlers.set(type, handler);
385
+ logger.debug(`[NativeBridge] Registered handler for: ${type}`);
386
+ }
387
+ /**
388
+ * Unregisters a handler for a specific message type
389
+ * @param type Message type to stop listening for
390
+ */
391
+ static off(type) {
392
+ this.handlers.delete(type);
393
+ logger.debug(`[NativeBridge] Unregistered handler for: ${type}`);
394
+ }
395
+ /**
396
+ * Clears all registered handlers
397
+ */
398
+ static clearHandlers() {
399
+ this.handlers.clear();
400
+ logger.debug("[NativeBridge] Cleared all handlers");
401
+ }
402
+ /**
403
+ * Checks if In-App Purchases are available on the device
404
+ * The native app will respond with a message containing availability status
405
+ *
406
+ * @example
407
+ * // Listen for the response
408
+ * NativeBridge.on("IAP_AVAILABILITY_RESULT", (payload) => {
409
+ * console.log("IAP available:", payload.available);
410
+ * });
411
+ *
412
+ * // Send the request
413
+ * NativeBridge.checkIAPAvailability();
414
+ */
415
+ static checkIAPAvailability() {
416
+ this.send("CHECK_IAP_AVAILABILITY" /* CHECK_IAP_AVAILABILITY */);
417
+ }
418
+ /**
419
+ * Requests notification permission from the native app
420
+ * The native app will respond with PUSH_PERMISSION_GRANTED or PUSH_PERMISSION_DENIED
421
+ *
422
+ * @example
423
+ * // Listen for the response
424
+ * NativeBridge.on("PUSH_PERMISSION_GRANTED", () => {
425
+ * console.log("Permission granted");
426
+ * });
427
+ *
428
+ * NativeBridge.on("PUSH_PERMISSION_DENIED", () => {
429
+ * console.log("Permission denied");
430
+ * });
431
+ *
432
+ * // Send the request
433
+ * NativeBridge.requestNotificationPermission();
434
+ */
435
+ static requestNotificationPermission() {
436
+ this.send("REQUEST_NOTIFICATION_PERMISSION" /* REQUEST_NOTIFICATION_PERMISSION */);
437
+ }
438
+ /**
439
+ * Requests available products for a specific game
440
+ * The native app will respond with PRODUCTS_RESULT containing product details
441
+ *
442
+ * @param gameId - The game ID to fetch products for
443
+ *
444
+ * @example
445
+ * // Listen for the response
446
+ * NativeBridge.on("PRODUCTS_RESULT", (payload) => {
447
+ * console.log("Products:", payload.products);
448
+ * });
449
+ *
450
+ * // Send the request
451
+ * NativeBridge.getProducts(123);
452
+ */
453
+ static getProducts(gameId) {
454
+ this.send("GET_PRODUCTS" /* GET_PRODUCTS */, { gameId });
455
+ }
456
+ /**
457
+ * Initiates a purchase for a specific product
458
+ * The native app will respond with PURCHASE_COMPLETE or PURCHASE_ERROR
459
+ *
460
+ * @param productId - The product ID to purchase
461
+ * @param userId - The user ID making the purchase
462
+ *
463
+ * @example
464
+ * // Listen for responses
465
+ * NativeBridge.on("PURCHASE_COMPLETE", (payload) => {
466
+ * console.log("Purchase successful:", payload.productId);
467
+ * });
468
+ *
469
+ * NativeBridge.on("PURCHASE_ERROR", (payload) => {
470
+ * console.error("Purchase failed:", payload.error);
471
+ * });
472
+ *
473
+ * // Initiate purchase
474
+ * NativeBridge.purchase("product_123", "user_456");
475
+ */
476
+ static purchase(productId, userId) {
477
+ this.send("PURCHASE" /* PURCHASE */, { productId, userId });
478
+ }
479
+ };
480
+
481
+ // src/utils/index.ts
482
+ function generateUUID() {
483
+ return uuidv4();
484
+ }
485
+
154
486
  // src/core/client.ts
155
487
  var HyveClient = class {
156
488
  telemetryConfig;
@@ -158,6 +490,7 @@ var HyveClient = class {
158
490
  sessionId;
159
491
  userId = null;
160
492
  jwtToken = null;
493
+ gameId = null;
161
494
  /**
162
495
  * Creates a new HyveClient instance
163
496
  * @param config Optional telemetry configuration
@@ -174,9 +507,9 @@ var HyveClient = class {
174
507
  this.apiBaseUrl = this.telemetryConfig.isDev ? "https://product-api.dev.hyve.gg" : "https://product-api.prod.hyve.gg";
175
508
  }
176
509
  this.sessionId = generateUUID();
177
- console.log("[Hyve SDK] Client initialized with sessionId:", this.sessionId);
178
- console.log("[Hyve SDK] API Base URL:", this.apiBaseUrl);
179
- console.log("[Hyve SDK] Environment:", this.telemetryConfig.isDev ? "dev" : "prod");
510
+ logger.info("Client initialized with sessionId:", this.sessionId);
511
+ logger.info("API Base URL:", this.apiBaseUrl);
512
+ logger.info("Environment:", this.telemetryConfig.isDev ? "dev" : "prod");
180
513
  }
181
514
  /**
182
515
  * Authenticates a user from URL parameters
@@ -188,7 +521,23 @@ var HyveClient = class {
188
521
  const params = urlParams ? parseUrlParams(urlParams) : parseUrlParams(window.location.search);
189
522
  if (params.hyveAccess) {
190
523
  this.jwtToken = params.hyveAccess;
191
- console.log("[Hyve SDK] JWT token extracted from hyve-access parameter");
524
+ logger.info("JWT token extracted from hyve-access parameter");
525
+ }
526
+ if (params.gameId) {
527
+ this.gameId = params.gameId;
528
+ logger.info("Game ID extracted from game-id parameter:", this.gameId);
529
+ }
530
+ if (this.jwtToken) {
531
+ logger.info("Authentication successful via JWT");
532
+ return true;
533
+ }
534
+ if (params.gameId) {
535
+ this.gameId = params.gameId;
536
+ logger.info("Game ID extracted from game-id parameter:", this.gameId);
537
+ }
538
+ if (this.jwtToken) {
539
+ logger.info("Authentication successful via JWT");
540
+ return true;
192
541
  }
193
542
  const authResult = verifyAuthentication({
194
543
  hyveToken: params.hyveToken,
@@ -197,76 +546,83 @@ var HyveClient = class {
197
546
  });
198
547
  if (authResult.isValid && authResult.address) {
199
548
  this.userId = authResult.address;
200
- console.log("[Hyve SDK] Authentication successful:", authResult.address);
201
- console.log("[Hyve SDK] Authentication method:", authResult.method);
549
+ logger.info("Authentication successful:", authResult.address);
550
+ logger.info("Authentication method:", authResult.method);
202
551
  return true;
203
552
  } else {
204
- console.error("[Hyve SDK] Authentication failed:", authResult.error);
553
+ logger.error("Authentication failed:", authResult.error);
205
554
  this.userId = null;
206
555
  return false;
207
556
  }
208
557
  } catch (error) {
209
- console.error("[Hyve SDK] Authentication error:", error);
558
+ logger.error("Authentication error:", error);
210
559
  this.userId = null;
211
560
  return false;
212
561
  }
213
562
  }
214
563
  /**
215
- * Sends a telemetry event
564
+ * Sends a user-level telemetry event using JWT authentication
565
+ * Requires JWT token, authenticated user, and game ID from URL parameters
216
566
  * @param eventLocation Location where the event occurred
217
567
  * @param eventCategory Main category of the event
218
568
  * @param eventAction Primary action taken
219
569
  * @param eventSubCategory Optional sub-category
220
570
  * @param eventSubAction Optional sub-action
221
- * @param eventDetails Optional event details
222
- * @param additionalData Optional additional data
571
+ * @param eventDetails Optional event details (object or JSON string)
572
+ * @param customData Optional custom data (object or JSON string)
573
+ * @param platformId Optional platform identifier
223
574
  * @returns Promise resolving to boolean indicating success
224
575
  */
225
- async sendTelemetry(eventLocation, eventCategory, eventAction, eventSubCategory, eventSubAction, eventDetails, additionalData) {
226
- if (!this.telemetryConfig.apiKey) {
227
- console.error("[Hyve Telemetry] API key not configured");
576
+ async sendTelemetry(eventLocation, eventCategory, eventAction, eventSubCategory, eventSubAction, eventDetails, customData, platformId) {
577
+ if (!this.jwtToken) {
578
+ logger.error("JWT token required. Call authenticateFromUrl first.");
228
579
  return false;
229
580
  }
230
- if (!this.userId) {
231
- console.warn("[Hyve Telemetry] No user ID - sending anonymous telemetry");
581
+ if (!this.gameId) {
582
+ logger.error("Game ID required. Ensure game-id URL parameter is set.");
583
+ return false;
232
584
  }
233
585
  try {
234
- let finalEventDetails = null;
235
- if (additionalData && Object.keys(additionalData).length > 0) {
236
- finalEventDetails = JSON.stringify(additionalData);
237
- } else if (eventDetails) {
238
- finalEventDetails = eventDetails;
239
- }
586
+ const toJsonString = (data) => {
587
+ if (!data) return null;
588
+ return typeof data === "string" ? data : JSON.stringify(data);
589
+ };
240
590
  const telemetryEvent = {
591
+ game_id: this.gameId,
241
592
  session_id: this.sessionId,
242
- hyve_user_id: this.userId || "anonymous",
593
+ platform_id: platformId || null,
243
594
  event_location: eventLocation,
244
595
  event_category: eventCategory,
245
596
  event_action: eventAction,
246
597
  event_sub_category: eventSubCategory || null,
247
598
  event_sub_action: eventSubAction || null,
248
- event_details: finalEventDetails
599
+ event_details: toJsonString(eventDetails),
600
+ custom_data: toJsonString(customData)
249
601
  };
250
- console.log("[Hyve Telemetry] Sending event:", telemetryEvent);
251
- const telemetryUrl = `${this.apiBaseUrl}/api/v1/partners/analytics/events`;
602
+ logger.debug("Sending telemetry event:", telemetryEvent);
603
+ const telemetryUrl = `${this.apiBaseUrl}/api/v1/telemetry/send`;
252
604
  const response = await fetch(telemetryUrl, {
253
605
  method: "POST",
254
606
  headers: {
255
607
  "Content-Type": "application/json",
256
- "X-API-KEY": this.telemetryConfig.apiKey
608
+ Authorization: `Bearer ${this.jwtToken}`
257
609
  },
258
610
  body: JSON.stringify(telemetryEvent)
259
611
  });
260
612
  if (response.ok) {
261
- console.log("[Hyve Telemetry] Event sent successfully:", response.status);
613
+ logger.info("Telemetry event sent successfully:", response.status);
262
614
  return true;
263
615
  } else {
264
616
  const errorText = await response.text();
265
- console.error("[Hyve Telemetry] Failed to send event:", response.status, errorText);
617
+ logger.error(
618
+ "Failed to send telemetry event:",
619
+ response.status,
620
+ errorText
621
+ );
266
622
  return false;
267
623
  }
268
624
  } catch (error) {
269
- console.error("[Hyve Telemetry] Error sending event:", error);
625
+ logger.error("Error sending telemetry event:", error);
270
626
  return false;
271
627
  }
272
628
  }
@@ -278,15 +634,18 @@ var HyveClient = class {
278
634
  */
279
635
  async callApi(endpoint, options = {}) {
280
636
  if (!this.jwtToken) {
281
- throw new Error("[Hyve SDK] No JWT token available. Call authenticateFromUrl first.");
637
+ throw new Error(
638
+ "No JWT token available. Call authenticateFromUrl first."
639
+ );
282
640
  }
283
641
  try {
284
642
  const url = `${this.apiBaseUrl}${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`;
643
+ logger.debug("Making API call to:", url);
285
644
  const response = await fetch(url, {
286
645
  ...options,
287
646
  headers: {
288
647
  "Content-Type": "application/json",
289
- "Authorization": `Bearer ${this.jwtToken}`,
648
+ Authorization: `Bearer ${this.jwtToken}`,
290
649
  ...options.headers
291
650
  }
292
651
  });
@@ -296,7 +655,7 @@ var HyveClient = class {
296
655
  }
297
656
  return await response.json();
298
657
  } catch (error) {
299
- console.error("[Hyve SDK] API call failed:", error);
658
+ logger.error("API call failed:", error);
300
659
  throw error;
301
660
  }
302
661
  }
@@ -329,8 +688,8 @@ var HyveClient = class {
329
688
  } else if (config.isDev !== void 0) {
330
689
  this.apiBaseUrl = config.isDev ? "https://product-api.dev.hyve.gg" : "https://product-api.prod.hyve.gg";
331
690
  }
332
- console.log("[Hyve SDK] Config updated");
333
- console.log("[Hyve SDK] API Base URL:", this.apiBaseUrl);
691
+ logger.info("Config updated");
692
+ logger.info("API Base URL:", this.apiBaseUrl);
334
693
  }
335
694
  /**
336
695
  * Gets the current user ID
@@ -353,6 +712,13 @@ var HyveClient = class {
353
712
  getJwtToken() {
354
713
  return this.jwtToken;
355
714
  }
715
+ /**
716
+ * Gets the current game ID
717
+ * @returns Current game ID or null if not available
718
+ */
719
+ getGameId() {
720
+ return this.gameId;
721
+ }
356
722
  /**
357
723
  * Gets the API base URL
358
724
  * @returns API base URL
@@ -380,7 +746,8 @@ var HyveClient = class {
380
746
  logout() {
381
747
  this.userId = null;
382
748
  this.jwtToken = null;
383
- console.log("[Hyve SDK] User logged out");
749
+ this.gameId = null;
750
+ logger.info("User logged out");
384
751
  }
385
752
  /**
386
753
  * Resets the client state
@@ -388,14 +755,18 @@ var HyveClient = class {
388
755
  reset() {
389
756
  this.logout();
390
757
  this.sessionId = generateUUID();
391
- console.log("[Hyve SDK] Client reset with new sessionId:", this.sessionId);
758
+ logger.info("Client reset with new sessionId:", this.sessionId);
392
759
  }
393
760
  };
394
761
  export {
395
762
  HyveClient,
763
+ Logger,
764
+ NativeBridge,
765
+ NativeMessageType,
396
766
  generateUUID,
397
767
  handleVerifyMessage,
398
768
  isDomainAllowed,
769
+ logger,
399
770
  parseUrlParams,
400
771
  validateSignature,
401
772
  verifyAuthentication,