Hyve SDK
The core SDK for integrating with the Hyve platform, providing authentication and telemetry capabilities for web applications and games.
Installation
npm install @hyve-sdk/js
# or
pnpm add @hyve-sdk/js
# or
yarn add @hyve-sdk/js
Quick Start
import { HyveClient } from '@hyve-sdk/js';
// Initialize the client
const client = new HyveClient({
apiKey: 'your-api-key-here',
isDev: true // Use dev environment (default)
});
// Authenticate from URL parameters
await client.authenticateFromUrl();
// Send telemetry event
await client.sendTelemetry(
'app', // event_location
'user', // event_category
'login', // event_action
null, // event_sub_category (optional)
null, // event_sub_action (optional)
null, // event_details (will be populated with additionalData JSON)
{ // additionalData (optional) - JSON stringified into event_details
timestamp: Date.now(),
platform: 'web'
}
);
Configuration
Client Configuration
const client = new HyveClient({
apiKey: 'your-api-key', // Required for telemetry
isDev: true // true = dev.hyve.gg, false = prod.hyve.gg
});
Environment Variables
Store your API key securely:
# .env
HYVE_API_KEY=your-api-key-here
const client = new HyveClient({
apiKey: process.env.HYVE_API_KEY,
isDev: process.env.NODE_ENV !== 'production'
});
Authentication
URL Parameter Authentication
The SDK supports two authentication formats via URL parameters:
Modern Token Format (Recommended)
https://yourapp.com?hyve-token=signature.address.randomBase64.timestamp
Legacy Format
https://yourapp.com?signature=0x...&message=encoded_message
Authenticating Users
// Authenticate from current URL
const isAuthenticated = await client.authenticateFromUrl();
if (isAuthenticated) {
console.log('User ID:', client.getUserId());
console.log('Session ID:', client.getSessionId());
}
// Or provide specific URL params
const params = new URLSearchParams(window.location.search);
const isAuthenticated = await client.authenticateFromUrl(params);
Checking Authentication Status
// Check if user is authenticated
if (client.isUserAuthenticated()) {
const userId = client.getUserId(); // User's wallet address
const sessionId = client.getSessionId(); // Unique session ID
}
JWT Authentication & API Integration
Overview
The SDK supports JWT-based authentication for making authenticated API calls to the Hyve platform. JWT tokens are passed via the hyve-access URL parameter and enable access to user-specific endpoints like inventory, profile data, and more.
JWT Authentication Flow
// JWT token is automatically extracted from URL
// URL format: https://your-game.com?hyve-access=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// Authenticate from URL (extracts both hyve-token and hyve-access)
await client.authenticateFromUrl();
// Check if JWT token is available
if (client.hasJwtToken()) {
console.log('JWT token available for API calls');
const token = client.getJwtToken(); // Get raw JWT token
}
Making API Calls
The SDK provides a generic callApi method for authenticated requests:
// GET request
const userData = await client.callApi('/api/v1/user');
// POST request with body
const result = await client.callApi('/api/v1/game/score', {
method: 'POST',
body: JSON.stringify({ score: 1000, level: 5 })
});
// With TypeScript typing
interface UserProfile {
id: string;
username: string;
email: string;
}
const profile = await client.callApi<UserProfile>('/api/v1/user');
Requirements:
- JWT token must be present (via
hyve-accessURL parameter) - User must be authenticated
- API calls automatically include
Authorization: Bearer {token}header
Error Handling
try {
const data = await client.callApi('/api/v1/user');
} catch (error) {
if (error.message.includes('No JWT token')) {
console.error('JWT token not available - check URL parameters');
} else if (error.message.includes('401')) {
console.error('JWT token expired or invalid');
} else {
console.error('API call failed:', error.message);
}
}
Inventory Management
Get User Inventory
Retrieve all items in the authenticated user's inventory:
const inventory = await client.getInventory();
console.log(`User has ${inventory.total_count} items`);
inventory.items.forEach(item => {
console.log(`${item.item_type}: ${item.quantity}x`);
if (item.metadata) {
console.log('Metadata:', item.metadata);
}
});
Response Structure:
interface Inventory {
items: InventoryItem[];
total_count: number;
}
interface InventoryItem {
id: string; // Unique item ID
user_id: string; // Owner's user ID
item_type: string; // Type: 'weapon', 'armor', 'consumable', etc.
item_id: string; // Specific item identifier
quantity: number; // Item quantity
metadata?: object; // Custom item data
created_at: string; // ISO timestamp
updated_at: string; // ISO timestamp
}
Get Specific Inventory Item
Fetch detailed information for a single inventory item:
const itemId = 'item-abc-123';
const item = await client.getInventoryItem(itemId);
console.log(`Item: ${item.item_type}`);
console.log(`Quantity: ${item.quantity}`);
console.log(`Item ID: ${item.item_id}`);
// Access custom metadata
if (item.metadata) {
console.log('Rarity:', item.metadata.rarity);
console.log('Level:', item.metadata.level);
console.log('Stats:', item.metadata.stats);
}
Inventory Example: Equipment System
class EquipmentManager {
constructor(hyveClient) {
this.client = hyveClient;
this.inventory = null;
}
async loadInventory() {
try {
// Check authentication
if (!this.client.hasJwtToken()) {
throw new Error('No JWT token - user must be authenticated');
}
// Fetch inventory
this.inventory = await this.client.getInventory();
// Track inventory load
await this.client.sendTelemetry(
'game', 'inventory', 'load', null, null, null,
{ total_items: this.inventory.total_count }
);
return this.inventory;
} catch (error) {
console.error('Failed to load inventory:', error);
throw error;
}
}
async getWeapons() {
if (!this.inventory) await this.loadInventory();
return this.inventory.items.filter(item => item.item_type === 'weapon');
}
async getItemDetails(itemId) {
try {
const item = await this.client.getInventoryItem(itemId);
// Track item view
await this.client.sendTelemetry(
'game', 'inventory', 'view_item', item.item_type, null, null,
{ item_id: itemId, quantity: item.quantity }
);
return item;
} catch (error) {
console.error('Failed to get item details:', error);
throw error;
}
}
getItemsByType(itemType) {
if (!this.inventory) return [];
return this.inventory.items.filter(item => item.item_type === itemType);
}
getItemById(itemId) {
if (!this.inventory) return null;
return this.inventory.items.find(item => item.id === itemId);
}
}
// Usage
const equipmentMgr = new EquipmentManager(client);
await equipmentMgr.loadInventory();
const weapons = await equipmentMgr.getWeapons();
Inventory API Endpoints
The SDK provides helper methods for these endpoints:
GET /api/v1/inventory- Get user's full inventoryGET /api/v1/inventory/:id- Get specific item details
// Get all inventory items
const inventory = await client.getInventory();
// Get specific item by ID
const item = await client.getInventoryItem('item-id-123');
Telemetry
Sending Telemetry Events
The sendTelemetry method provides full control over event tracking:
await client.sendTelemetry(
eventLocation, // Required: Where the event occurred
eventCategory, // Required: Main category
eventAction, // Required: Action taken
eventSubCategory, // Optional: Sub-category (pass null if not needed)
eventSubAction, // Optional: Sub-action (pass null if not needed)
eventDetails, // Optional: Human-readable description (pass null if not needed)
additionalData // Optional: Additional data object (pass null if not needed)
);
Telemetry Fields
All fields are always sent to the backend (with null for optional fields):
| Field | Type | Description |
|---|---|---|
session_id | string | Unique session identifier (auto-generated) |
hyve_user_id | string | User's wallet address or 'anonymous' |
event_location | string | Where the event occurred |
event_category | string | Main category of event |
event_action | string | Action taken |
event_sub_category | string | null | Sub-category for granular classification |
event_sub_action | string | null | Sub-action for detailed tracking |
event_details | string | null | JSON stringified additional data or description |
Examples
// Simple event
await client.sendTelemetry(
'app', 'system', 'startup',
null, null, null, null
);
// Event with all fields
await client.sendTelemetry(
'game', // location
'player', // category
'achievement', // action
'combat', // sub-category
'first_boss_defeat', // sub-action
null, // event_details will be JSON stringified additionalData
{ // additionalData - becomes JSON in event_details
bossName: 'Dragon',
playerLevel: 5,
timeElapsed: 300,
damageDealt: 1500,
description: 'Player defeated the first boss'
}
);
// User action tracking
await client.sendTelemetry(
'app',
'navigation',
'click',
'menu',
'settings',
null, // event_details will be JSON stringified additionalData
{ // additionalData - becomes JSON in event_details
source: 'header',
timestamp: Date.now(),
description: 'User opened settings menu'
}
);
// Error tracking
await client.sendTelemetry(
'app',
'error',
'exception',
'network',
null,
null, // event_details will be JSON stringified additionalData
{ // additionalData - becomes JSON in event_details
errorCode: 'NETWORK_TIMEOUT',
endpoint: '/api/profile',
retryCount: 3,
description: 'Failed to load user profile'
}
);
API Reference
HyveClient
Constructor
new HyveClient(config?: TelemetryConfig)
Methods
| Method | Returns | Description |
|---|---|---|
authenticateFromUrl(urlParams?) | Promise<boolean> | Authenticate user from URL parameters |
sendTelemetry(...) | Promise<boolean> | Send telemetry event |
getUserId() | string | null | Get authenticated user's ID |
getSessionId() | string | Get current session ID |
isUserAuthenticated() | boolean | Check if user is authenticated |
updateTelemetryConfig(config) | void | Update telemetry configuration |
logout() | void | Clear user authentication |
reset() | void | Reset client with new session |
Types
interface TelemetryConfig {
apiKey?: string; // API key for telemetry service
isDev?: boolean; // Use dev environment (default: true)
}
interface TelemetryAdditionalData {
[key: string]: any; // Additional data object (JSON stringified into event_details)
}
Best Practices
1. API Key Management
// Use environment variables
const client = new HyveClient({
apiKey: process.env.HYVE_API_KEY,
isDev: process.env.NODE_ENV !== 'production'
});
2. Error Handling
try {
const success = await client.sendTelemetry(...);
if (!success) {
console.warn('Telemetry failed to send');
// Handle gracefully - don't break app flow
}
} catch (error) {
console.error('Telemetry error:', error);
// Continue app execution
}
3. Anonymous Telemetry
// Telemetry works without authentication
// User ID will be 'anonymous'
const client = new HyveClient({ apiKey: 'key' });
// Still works - sends as anonymous user
await client.sendTelemetry('app', 'action', 'click', null, null, null, null);
4. Session Management
// Sessions persist until reset
const sessionId = client.getSessionId();
// Create new session if needed
client.reset(); // New session ID generated
Troubleshooting
API Key Not Working
- Verify the API key is correct
- Check you're using the right environment (dev vs prod)
- Look for network errors in browser console
- Ensure CORS is properly configured
Authentication Failing
- Check URL parameter format
- Verify signature is valid
- Ensure timestamp is recent (within 5 minutes)
- Check browser console for specific errors
Telemetry Not Sending
- API key must be configured
- Check network tab for 4xx/5xx responses
- Verify required fields are provided
- Look for console errors