@hyve-sdk/js 1.2.2 → 1.3.1-canary.1

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/README.md CHANGED
@@ -20,6 +20,8 @@ pnpm add @hyve-sdk/js
20
20
  - **API Integration**: Authenticated API calls with JWT token support
21
21
  - **Inventory Management**: Built-in methods for user inventory operations
22
22
  - **Telemetry Tracking**: Session-based analytics and event tracking
23
+ - **Ads Integration**: Google H5 Games Ads support (disabled by default)
24
+ - **Native Bridge**: Type-safe communication with React Native WebView apps
23
25
  - **Security Utilities**: Domain validation and referrer checking
24
26
  - **URL Parameter Parsing**: Easy extraction of authentication parameters
25
27
  - **UUID Generation**: Built-in UUID v4 generation
@@ -278,10 +280,199 @@ if (item.metadata) {
278
280
  - `GET /api/v1/inventory` - Get all inventory items
279
281
  - `GET /api/v1/inventory/:id` - Get specific item
280
282
 
283
+ ## Ads Integration
284
+
285
+ The SDK includes support for Google H5 Games Ads. **Ads are disabled by default** and must be explicitly enabled in the configuration.
286
+
287
+ ### Quick Start
288
+
289
+ ```typescript
290
+ import { HyveClient } from "@hyve-sdk/js";
291
+
292
+ // Enable ads in initial config
293
+ const client = new HyveClient({
294
+ isDev: true,
295
+ ads: {
296
+ enabled: true, // Must be set to true
297
+ sound: 'on',
298
+ debug: true,
299
+ onBeforeAd: (type) => {
300
+ console.log('Pausing game for ad:', type);
301
+ game.pause();
302
+ },
303
+ onAfterAd: (type) => {
304
+ console.log('Resuming game after ad');
305
+ game.resume();
306
+ },
307
+ onRewardEarned: () => {
308
+ console.log('User earned reward!');
309
+ player.coins += 100;
310
+ }
311
+ }
312
+ });
313
+
314
+ // Show different ad types
315
+ const result = await client.showAd('rewarded');
316
+ if (result.success) {
317
+ console.log('User watched the ad!');
318
+ }
319
+
320
+ await client.showAd('interstitial'); // Between levels
321
+ await client.showAd('preroll'); // Game start
322
+ ```
323
+
324
+ ### Prerequisites
325
+
326
+ Add the Google H5 Games Ads SDK to your HTML:
327
+
328
+ ```html
329
+ <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
330
+ <script>
331
+ window.adBreak = window.adBreak || function(o) {
332
+ (window.adsbygoogle = window.adsbygoogle || []).push(o);
333
+ };
334
+ window.adConfig = window.adConfig || function(o) {
335
+ (window.adsbygoogle = window.adsbygoogle || []).push(o);
336
+ };
337
+ </script>
338
+ ```
339
+
340
+ ### Ad Types
341
+
342
+ | Type | Use Case |
343
+ |------|----------|
344
+ | `rewarded` | User watches full ad for reward (coins, lives, etc.) |
345
+ | `interstitial` | Between levels or game screens |
346
+ | `preroll` | Before game starts |
347
+
348
+ ### Configuration
349
+
350
+ ```typescript
351
+ interface AdConfig {
352
+ enabled?: boolean; // Enable/disable ads (default: false)
353
+ sound?: 'on' | 'off'; // Sound setting (default: 'on')
354
+ debug?: boolean; // Enable debug logging (default: false)
355
+ onBeforeAd?: (type) => void; // Called before ad shows
356
+ onAfterAd?: (type) => void; // Called after ad finishes
357
+ onRewardEarned?: () => void; // Called when user earns reward
358
+ }
359
+ ```
360
+
361
+ ### Methods
362
+
363
+ ```typescript
364
+ // Configure ads after initialization
365
+ client.configureAds({ enabled: true, sound: 'off' });
366
+
367
+ // Show an ad
368
+ const result = await client.showAd('rewarded');
369
+
370
+ // Check status
371
+ client.areAdsEnabled(); // Boolean
372
+ client.areAdsReady(); // Boolean
373
+ ```
374
+
375
+ See [docs/ads.md](./docs/ads.md) for detailed documentation and examples.
376
+
281
377
  **Requirements:**
282
378
  - JWT token must be available (via `hyve-access` URL parameter)
283
379
  - User must be authenticated
284
380
 
381
+ ## Native Bridge (React Native WebView)
382
+
383
+ Provides type-safe bidirectional communication between your web application and the React Native mobile app.
384
+
385
+ ### Quick Start
386
+
387
+ ```typescript
388
+ import { NativeBridge, NativeMessageType } from "@hyve-sdk/js";
389
+
390
+ // Initialize on app start
391
+ if (NativeBridge.isNativeContext()) {
392
+ NativeBridge.initialize();
393
+ }
394
+ ```
395
+
396
+ ### Check IAP Availability
397
+
398
+ Request information about In-App Purchase availability:
399
+
400
+ ```typescript
401
+ // Register response handler
402
+ NativeBridge.on("IAP_AVAILABILITY_RESULT", (payload) => {
403
+ if (payload.available) {
404
+ console.log("IAP is available on this device");
405
+ // Show purchase UI
406
+ } else {
407
+ console.log("IAP is not available");
408
+ // Hide purchase features
409
+ }
410
+ });
411
+
412
+ // Send request
413
+ NativeBridge.checkIAPAvailability();
414
+ ```
415
+
416
+ ### Request Push Notifications
417
+
418
+ Request notification permissions from the native app:
419
+
420
+ ```typescript
421
+ // Register response handlers
422
+ NativeBridge.on("PUSH_PERMISSION_GRANTED", (payload) => {
423
+ console.log("Push notifications enabled");
424
+ console.log("Token:", payload?.token);
425
+ });
426
+
427
+ NativeBridge.on("PUSH_PERMISSION_DENIED", () => {
428
+ console.log("Push notifications disabled");
429
+ });
430
+
431
+ // Send request
432
+ NativeBridge.requestNotificationPermission();
433
+ ```
434
+
435
+ ### Send Custom Messages
436
+
437
+ Send custom messages to the native app:
438
+
439
+ ```typescript
440
+ // Send message with payload
441
+ NativeBridge.send("CUSTOM_EVENT", {
442
+ action: "open_settings",
443
+ data: { setting: "notifications" }
444
+ });
445
+
446
+ // Listen for custom responses
447
+ NativeBridge.on("CUSTOM_RESPONSE", (payload) => {
448
+ console.log("Received:", payload);
449
+ });
450
+ ```
451
+
452
+ ### Built-in Message Types
453
+
454
+ **Web → Native:**
455
+ - `CHECK_IAP_AVAILABILITY` - Check if IAP is available
456
+ - `REQUEST_NOTIFICATION_PERMISSION` - Request push notification permission
457
+
458
+ **Native → Web:**
459
+ - `IAP_AVAILABILITY_RESULT` - Response with IAP availability
460
+ - `PUSH_PERMISSION_GRANTED` - Push permission granted
461
+ - `PUSH_PERMISSION_DENIED` - Push permission denied
462
+
463
+ ### API Reference
464
+
465
+ - `NativeBridge.isNativeContext()` - Check if running in React Native WebView
466
+ - `NativeBridge.initialize()` - Initialize message listener
467
+ - `NativeBridge.send(type, payload?)` - Send message to native
468
+ - `NativeBridge.on(type, handler)` - Register message handler
469
+ - `NativeBridge.off(type)` - Unregister message handler
470
+ - `NativeBridge.clearHandlers()` - Clear all handlers
471
+ - `NativeBridge.checkIAPAvailability()` - Helper for IAP check
472
+ - `NativeBridge.requestNotificationPermission()` - Helper for notification permission
473
+
474
+ For complete documentation, see [docs/NATIVE_BRIDGE.md](./docs/NATIVE_BRIDGE.md).
475
+
285
476
  ## Client Methods Reference
286
477
 
287
478
  ### Authentication
package/dist/index.d.mts CHANGED
@@ -63,7 +63,121 @@ interface Inventory {
63
63
  items: InventoryItem[];
64
64
  total_count: number;
65
65
  }
66
+ /**
67
+ * Ads configuration options
68
+ * Ads are disabled by default and must be explicitly enabled
69
+ */
70
+ interface AdConfig$1 {
71
+ /** Enable/disable ads (default: false) */
72
+ enabled?: boolean;
73
+ /** Sound setting for ads (default: 'on') */
74
+ sound?: 'on' | 'off';
75
+ /** Enable debug logging (default: false) */
76
+ debug?: boolean;
77
+ /** Callback before ad is shown */
78
+ onBeforeAd?: (type: 'rewarded' | 'interstitial' | 'preroll') => void;
79
+ /** Callback after ad is shown */
80
+ onAfterAd?: (type: 'rewarded' | 'interstitial' | 'preroll') => void;
81
+ /** Callback when user earns a reward (rewarded ads only) */
82
+ onRewardEarned?: () => void;
83
+ }
84
+
85
+ /**
86
+ * Ads Service for Hyve SDK
87
+ *
88
+ * Simple wrapper around Google H5 Games Ads with configurable enable/disable.
89
+ * Ads are OFF by default and must be explicitly enabled in SDK config.
90
+ *
91
+ * Prerequisites:
92
+ * - Google H5 Games Ads SDK script must be loaded in HTML:
93
+ * <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
94
+ * <script>
95
+ * window.adBreak = window.adBreak || function(o) { (window.adsbygoogle = window.adsbygoogle || []).push(o); };
96
+ * window.adConfig = window.adConfig || function(o) { (window.adsbygoogle = window.adsbygoogle || []).push(o); };
97
+ * </script>
98
+ *
99
+ * @packageDocumentation
100
+ */
101
+ type AdType = 'rewarded' | 'interstitial' | 'preroll';
102
+ interface AdResult {
103
+ success: boolean;
104
+ type: AdType;
105
+ error?: Error;
106
+ requestedAt: number;
107
+ completedAt: number;
108
+ }
109
+ interface AdConfig {
110
+ enabled?: boolean;
111
+ sound?: 'on' | 'off';
112
+ debug?: boolean;
113
+ onBeforeAd?: (type: AdType) => void;
114
+ onAfterAd?: (type: AdType) => void;
115
+ onRewardEarned?: () => void;
116
+ }
117
+ interface GoogleAdBreakConfig {
118
+ type: 'reward' | 'next' | 'start';
119
+ name: string;
120
+ beforeAd?: () => void;
121
+ afterAd?: () => void;
122
+ beforeReward?: (showAdFn: () => void) => void;
123
+ adViewed?: () => void;
124
+ adDismissed?: () => void;
125
+ adBreakDone?: (info?: any) => void;
126
+ }
127
+ interface GoogleAdConfigOptions {
128
+ sound?: 'on' | 'off';
129
+ preloadAdBreaks?: 'on' | 'off';
130
+ onReady?: () => void;
131
+ }
132
+ declare global {
133
+ interface Window {
134
+ adBreak?: (config: GoogleAdBreakConfig) => void;
135
+ adConfig?: (config: GoogleAdConfigOptions) => void;
136
+ }
137
+ }
138
+ /**
139
+ * Simple Ads Manager
140
+ * Ads are disabled by default
141
+ */
142
+ declare class AdsService {
143
+ private config;
144
+ private initialized;
145
+ private ready;
146
+ /**
147
+ * Configure the ads service
148
+ * Must set enabled: true to activate ads
149
+ */
150
+ configure(config: AdConfig): void;
151
+ /**
152
+ * Initialize the ads system
153
+ */
154
+ private initialize;
155
+ /**
156
+ * Show an ad
157
+ * Returns immediately if ads are disabled
158
+ */
159
+ show(type: AdType): Promise<AdResult>;
160
+ /**
161
+ * Show an ad break
162
+ */
163
+ private showAdBreak;
164
+ /**
165
+ * Check if ads are enabled
166
+ */
167
+ isEnabled(): boolean;
168
+ /**
169
+ * Check if ads are ready to show
170
+ */
171
+ isReady(): boolean;
172
+ }
66
173
 
174
+ /**
175
+ * HyveClient configuration options
176
+ */
177
+ interface HyveClientConfig extends TelemetryConfig {
178
+ /** Ads configuration (disabled by default) */
179
+ ads?: AdConfig$1;
180
+ }
67
181
  /**
68
182
  * HyveClient provides telemetry and authentication functionality for Hyve games
69
183
  */
@@ -74,11 +188,12 @@ declare class HyveClient {
74
188
  private userId;
75
189
  private jwtToken;
76
190
  private gameId;
191
+ private adsService;
77
192
  /**
78
193
  * Creates a new HyveClient instance
79
- * @param config Optional telemetry configuration
194
+ * @param config Optional configuration including telemetry and ads
80
195
  */
81
- constructor(config?: TelemetryConfig);
196
+ constructor(config?: HyveClientConfig);
82
197
  /**
83
198
  * Authenticates a user from URL parameters
84
199
  * @param urlParams URL parameters or search string
@@ -165,7 +280,75 @@ declare class HyveClient {
165
280
  * Resets the client state
166
281
  */
167
282
  reset(): void;
283
+ /**
284
+ * Configure ads service
285
+ * @param config Ads configuration
286
+ */
287
+ configureAds(config: AdConfig$1): void;
288
+ /**
289
+ * Show an ad
290
+ * @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
291
+ * @returns Promise resolving to ad result
292
+ */
293
+ showAd(type: AdType): Promise<AdResult>;
294
+ /**
295
+ * Check if ads are enabled
296
+ * @returns Boolean indicating if ads are enabled
297
+ */
298
+ areAdsEnabled(): boolean;
299
+ /**
300
+ * Check if ads are ready to show
301
+ * @returns Boolean indicating if ads are ready
302
+ */
303
+ areAdsReady(): boolean;
304
+ }
305
+
306
+ /**
307
+ * Logger utility for the Hyve SDK
308
+ * Automatically enabled in development (NODE_ENV !== 'production')
309
+ */
310
+ type LogLevel = "debug" | "info" | "warn" | "error";
311
+ declare class Logger {
312
+ private config;
313
+ constructor();
314
+ /**
315
+ * Initialize logger configuration based on NODE_ENV
316
+ */
317
+ private initializeConfig;
318
+ /**
319
+ * Set which log levels to display
320
+ */
321
+ setLevels(levels: LogLevel[]): void;
322
+ /**
323
+ * Check if logging is enabled
324
+ */
325
+ isEnabled(): boolean;
326
+ /**
327
+ * Internal log method
328
+ */
329
+ private log;
330
+ /**
331
+ * Log a debug message
332
+ */
333
+ debug(...args: unknown[]): void;
334
+ /**
335
+ * Log an info message
336
+ */
337
+ info(...args: unknown[]): void;
338
+ /**
339
+ * Log a warning message
340
+ */
341
+ warn(...args: unknown[]): void;
342
+ /**
343
+ * Log an error message
344
+ */
345
+ error(...args: unknown[]): void;
346
+ /**
347
+ * Create a child logger with a specific prefix
348
+ */
349
+ child(prefix: string): Logger;
168
350
  }
351
+ declare const logger: Logger;
169
352
 
170
353
  /**
171
354
  * Parses URL search parameters and returns commonly used values
@@ -218,11 +401,6 @@ declare function verifyAuthentication(params: {
218
401
  method: "modern" | "legacy" | "none";
219
402
  error?: string;
220
403
  };
221
- /**
222
- * Generates a random UUID (v4) using the uuid library
223
- * @returns A string containing a randomly generated UUID
224
- */
225
- declare function generateUUID(): string;
226
404
  /**
227
405
  * Checks if the current domain is in the list of allowed domains
228
406
  * @param allowedDomains Array of allowed domains or a single domain string
@@ -230,4 +408,172 @@ declare function generateUUID(): string;
230
408
  */
231
409
  declare function isDomainAllowed(allowedDomains?: string | string[], hostname?: string): boolean;
232
410
 
233
- export { HyveClient, type Inventory, type InventoryItem, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };
411
+ /**
412
+ * Message structure for WebView to Native communication
413
+ */
414
+ interface NativeMessage<T = any> {
415
+ type: string;
416
+ payload?: T;
417
+ timestamp?: number;
418
+ }
419
+ /**
420
+ * Message types for native communication
421
+ */
422
+ declare enum NativeMessageType {
423
+ /** Check if In-App Purchases are available on the device */
424
+ CHECK_IAP_AVAILABILITY = "CHECK_IAP_AVAILABILITY",
425
+ /** Request notification permission from the native app */
426
+ REQUEST_NOTIFICATION_PERMISSION = "REQUEST_NOTIFICATION_PERMISSION",
427
+ /** Request available products for a game */
428
+ GET_PRODUCTS = "GET_PRODUCTS",
429
+ /** Initiate a purchase */
430
+ PURCHASE = "PURCHASE",
431
+ /** Response to CHECK_IAP_AVAILABILITY request */
432
+ IAP_AVAILABILITY_RESULT = "IAP_AVAILABILITY_RESULT",
433
+ /** Push notification permission was granted */
434
+ PUSH_PERMISSION_GRANTED = "PUSH_PERMISSION_GRANTED",
435
+ /** Push notification permission was denied */
436
+ PUSH_PERMISSION_DENIED = "PUSH_PERMISSION_DENIED",
437
+ /** Response with available products */
438
+ PRODUCTS_RESULT = "PRODUCTS_RESULT",
439
+ /** Purchase completed successfully */
440
+ PURCHASE_COMPLETE = "PURCHASE_COMPLETE",
441
+ /** Purchase failed or was cancelled */
442
+ PURCHASE_ERROR = "PURCHASE_ERROR"
443
+ }
444
+ /**
445
+ * Message handler function type for receiving messages from native
446
+ */
447
+ type NativeMessageHandler<T = any> = (payload: T) => void | Promise<void>;
448
+ /**
449
+ * NativeBridge - Provides utilities for WebView to React Native communication
450
+ *
451
+ * @example
452
+ * // Send message to React Native
453
+ * NativeBridge.send(NativeMessageType.CHECK_IAP_AVAILABILITY);
454
+ *
455
+ * // Listen for messages from React Native
456
+ * NativeBridge.on("PUSH_PERMISSION_GRANTED", (payload) => {
457
+ * console.log("Permission granted:", payload);
458
+ * });
459
+ *
460
+ * // Check if running in React Native WebView
461
+ * if (NativeBridge.isNativeContext()) {
462
+ * NativeBridge.checkIAPAvailability();
463
+ * }
464
+ */
465
+ declare class NativeBridge {
466
+ private static handlers;
467
+ private static isInitialized;
468
+ /**
469
+ * Checks if the app is running inside a React Native WebView
470
+ */
471
+ static isNativeContext(): boolean;
472
+ /**
473
+ * Initializes the native bridge message listener
474
+ * Call this once when your app starts
475
+ */
476
+ static initialize(): void;
477
+ /**
478
+ * Handles incoming messages from React Native
479
+ */
480
+ private static handleNativeMessage;
481
+ /**
482
+ * Sends a message to React Native
483
+ * @param type Message type
484
+ * @param payload Optional payload data
485
+ */
486
+ static send<T = any>(type: string, payload?: T): void;
487
+ /**
488
+ * Registers a handler for messages from React Native
489
+ * @param type Message type to listen for
490
+ * @param handler Function to call when message is received
491
+ */
492
+ static on<T = any>(type: string, handler: NativeMessageHandler<T>): void;
493
+ /**
494
+ * Unregisters a handler for a specific message type
495
+ * @param type Message type to stop listening for
496
+ */
497
+ static off(type: string): void;
498
+ /**
499
+ * Clears all registered handlers
500
+ */
501
+ static clearHandlers(): void;
502
+ /**
503
+ * Checks if In-App Purchases are available on the device
504
+ * The native app will respond with a message containing availability status
505
+ *
506
+ * @example
507
+ * // Listen for the response
508
+ * NativeBridge.on("IAP_AVAILABILITY_RESULT", (payload) => {
509
+ * console.log("IAP available:", payload.available);
510
+ * });
511
+ *
512
+ * // Send the request
513
+ * NativeBridge.checkIAPAvailability();
514
+ */
515
+ static checkIAPAvailability(): void;
516
+ /**
517
+ * Requests notification permission from the native app
518
+ * The native app will respond with PUSH_PERMISSION_GRANTED or PUSH_PERMISSION_DENIED
519
+ *
520
+ * @example
521
+ * // Listen for the response
522
+ * NativeBridge.on("PUSH_PERMISSION_GRANTED", () => {
523
+ * console.log("Permission granted");
524
+ * });
525
+ *
526
+ * NativeBridge.on("PUSH_PERMISSION_DENIED", () => {
527
+ * console.log("Permission denied");
528
+ * });
529
+ *
530
+ * // Send the request
531
+ * NativeBridge.requestNotificationPermission();
532
+ */
533
+ static requestNotificationPermission(): void;
534
+ /**
535
+ * Requests available products for a specific game
536
+ * The native app will respond with PRODUCTS_RESULT containing product details
537
+ *
538
+ * @param gameId - The game ID to fetch products for
539
+ *
540
+ * @example
541
+ * // Listen for the response
542
+ * NativeBridge.on("PRODUCTS_RESULT", (payload) => {
543
+ * console.log("Products:", payload.products);
544
+ * });
545
+ *
546
+ * // Send the request
547
+ * NativeBridge.getProducts(123);
548
+ */
549
+ static getProducts(gameId: number): void;
550
+ /**
551
+ * Initiates a purchase for a specific product
552
+ * The native app will respond with PURCHASE_COMPLETE or PURCHASE_ERROR
553
+ *
554
+ * @param productId - The product ID to purchase
555
+ * @param userId - The user ID making the purchase
556
+ *
557
+ * @example
558
+ * // Listen for responses
559
+ * NativeBridge.on("PURCHASE_COMPLETE", (payload) => {
560
+ * console.log("Purchase successful:", payload.productId);
561
+ * });
562
+ *
563
+ * NativeBridge.on("PURCHASE_ERROR", (payload) => {
564
+ * console.error("Purchase failed:", payload.error);
565
+ * });
566
+ *
567
+ * // Initiate purchase
568
+ * NativeBridge.purchase("product_123", "user_456");
569
+ */
570
+ static purchase(productId: string, userId: string): void;
571
+ }
572
+
573
+ /**
574
+ * Generates a random UUID (v4) using the uuid library
575
+ * @returns A string containing a randomly generated UUID
576
+ */
577
+ declare function generateUUID(): string;
578
+
579
+ export { type AdConfig$1 as AdConfig, type AdResult, type AdType, AdsService, HyveClient, type HyveClientConfig, type Inventory, type InventoryItem, Logger, NativeBridge, type NativeMessage, type NativeMessageHandler, NativeMessageType, type TelemetryAdditionalData, type TelemetryConfig, type TelemetryEvent, generateUUID, handleVerifyMessage, isDomainAllowed, logger, parseUrlParams, validateSignature, verifyAuthentication, verifyHyveToken };