@series-inc/venus-sdk 2.4.1 → 3.0.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/README.md CHANGED
@@ -17,21 +17,215 @@ The Venus SDK is built on a client-server RPC architecture:
17
17
  - **Mock Implementations** - Complete mock APIs for local development
18
18
  - **Venus API** - Low-level platform interface
19
19
 
20
- ### Core Components
20
+ ### Usage
21
21
 
22
22
  ```typescript
23
- import { createHost, VenusAPI } from 'venus-sdk'
23
+ import { default as VenusAPI } from '@series-inc/venus-sdk/api'
24
24
 
25
- // Create Venus API instance
26
- const venusApi = new VenusAPI()
27
- await venusApi.initializeAsync()
25
+ // Initialize the API
26
+ await VenusAPI.initializeAsync()
27
+ ```
28
+
29
+ ## API Overview
30
+
31
+ ### Profile API
32
+
33
+ ```typescript
34
+ // Get current user profile (synchronous)
35
+ const profile = VenusAPI.profile.getCurrentProfile()
36
+ console.log(profile.name, profile.username)
37
+ ```
38
+ ---
39
+
40
+ ### Safe Area & HUD Insets
41
+
42
+ ```typescript
43
+ // Static safe area from initialization (baseline padding)
44
+ const safeArea = VenusAPI.config.ui.safeArea
45
+ layout.style.paddingTop = `${safeArea.top}px`
46
+ layout.style.paddingBottom = `${safeArea.bottom}px`
47
+
48
+ // Dynamic HUD insets arrive with lifecycle events
49
+ VenusAPI.lifecycle.onShow(({ hudInsets }) => {
50
+ applyInsets(hudInsets, 'preview')
51
+ })
52
+
53
+ VenusAPI.lifecycle.onPlay(({ hudInsets }) => {
54
+ applyInsets(hudInsets, 'fullscreen')
55
+ })
56
+
57
+ function applyInsets(insets, mode) {
58
+ // Use whichever inset is larger to avoid overlap with host UI
59
+ const top = Math.max(VenusAPI.config.ui.safeArea.top, insets.top)
60
+ canvas.style.paddingTop = `${top}px`
61
+ canvas.dataset.mode = mode
62
+ }
63
+ ```
64
+
65
+ `safeArea` provides a static baseline defined at initialization. `hudInsets` reflect the live host UI chrome and differ between preview (`onShow`) and fullscreen (`onPlay`) contexts.
66
+
67
+ ---
68
+
69
+ ### Ads API
70
+
71
+ ```typescript
72
+ // Check if rewarded ad is ready
73
+ const rewardedReady = await VenusAPI.ads.isRewardedAdReadyAsync()
28
74
 
29
- // Create Host (false = remote, true = mock)
30
- const host = createHost(venusApi, false)
31
- await host.initialize()
75
+ // Show interstitial ad
76
+ const interstitialShown = await VenusAPI.ads.showInterstitialAd()
77
+ if (interstitialShown) {
78
+ // Interstitial ad was displayed
79
+ }
80
+
81
+ // Show rewarded video ad
82
+ const rewardEarned = await VenusAPI.ads.showRewardedAdAsync()
83
+ if (rewardEarned) {
84
+ // User watched the full video and earned reward
85
+ }
32
86
  ```
87
+ ---
33
88
 
34
- ## API Reference
89
+ ### Haptics API
90
+
91
+ ```typescript
92
+ // Trigger haptic feedback
93
+ await VenusAPI.haptics.triggerHapticAsync('success')
94
+ await VenusAPI.haptics.triggerHapticAsync('warning')
95
+ await VenusAPI.haptics.triggerHapticAsync('error')
96
+ await VenusAPI.haptics.triggerHapticAsync('light')
97
+ await VenusAPI.haptics.triggerHapticAsync('medium')
98
+ await VenusAPI.haptics.triggerHapticAsync('heavy')
99
+ ```
100
+ ---
101
+
102
+ ### Local Notifications API
103
+
104
+ ```typescript
105
+ // Schedule a delayed notification (minimal - required params only)
106
+ const id = await VenusApi.notifications.scheduleAsync(
107
+ 'Notification Title',
108
+ 'Notification Body',
109
+ 60 // Delay in seconds
110
+ )
111
+
112
+ // Schedule with optional notification ID
113
+ const id = await VenusApi.notifications.scheduleAsync(
114
+ 'Notification Title',
115
+ 'Notification Body',
116
+ 60,
117
+ 'custom-notification-id'
118
+ )
119
+
120
+ // Schedule with all optional settings
121
+ const id = await VenusApi.notifications.scheduleAsync(
122
+ 'Notification Title',
123
+ 'Notification Body',
124
+ 60,
125
+ 'custom-notification-id',
126
+ {
127
+ priority: 100, // 0-100, default 50
128
+ groupId: 'reminders', // Group related notifications
129
+ payload: { key: 'value' } // Custom data
130
+ }
131
+ )
132
+
133
+ // Cancel a notification
134
+ await VenusApi.notifications.cancelNotification(notificationId)
135
+
136
+ // Get all scheduled notifications
137
+ await VenusApi.notifications.getAllScheduledLocalNotifications()
138
+ ```
139
+ ---
140
+
141
+ ### Loader API
142
+
143
+ The preloader is opt-in by default. In order to opt in, you must add
144
+ ```typescript
145
+ await VenusAPI.initializeAsync({ usePreloader: true })
146
+ ```
147
+
148
+ ```typescript
149
+ // Activating and dismissing the preloader
150
+ await VenusApi.preloader.showLoadScreen()
151
+ await VenusApi.preloader.hideLoadScreen()
152
+ ```
153
+ ---
154
+
155
+ ### Custom Funnel Events API
156
+
157
+ ```typescript
158
+ // Record a custom analytics event
159
+ await VenusApi.analytics.recordCustomEvent('level_completed', {
160
+ level: 5,
161
+ score: 1250,
162
+ time: 45.2
163
+ })
164
+
165
+ // Track funnel step with optional funnel name
166
+ await VenusApi.analytics.trackFunnelStep(1, 'tutorial_started', 'onboarding')
167
+ await VenusApi.analytics.trackFunnelStep(2, 'tutorial_completed', 'onboarding')
168
+ ```
169
+ ---
170
+
171
+ ### IAP API
172
+
173
+ ```typescript
174
+ // get VBucks/Hard Currency balance
175
+ await VenusApi.iap.getHardCurrencyBalance()
176
+ // Spend VBucks/Hard Currency
177
+ await VenusApi.iap.spendCurrency('yourProductID', 3)
178
+ // Open Venus Store
179
+ await VenusApi.iap.openStore()
180
+ // Get Currency Icon
181
+ await VenusApi.iap.getCurrencyIcon()
182
+ ```
183
+ ---
184
+
185
+ ### Saves API
186
+
187
+ ```typescript
188
+ // Get an item from storage
189
+ await VenusApi.storage.getItem('playerData')
190
+ // Set an item in storage
191
+ await VenusApi.storage.setItem('playerData', JSON.stringify({ level: 10 }))
192
+ // Remove an item from storage
193
+ await VenusApi.storage.removeItem('playerData')
194
+ // Get storage length
195
+ await VenusApi.storage.length()
196
+ // Get key at specific index
197
+ await VenusApi.storage.key(0)
198
+ // Clear all items from storage
199
+ await VenusApi.storage.clear()
200
+ // Set multiple items at once
201
+ await VenusApi.storage.setMultipleItems([
202
+ { key: 'playerData', value: JSON.stringify({ level: 10 }) },
203
+ { key: 'settings', value: JSON.stringify({ sound: true }) }
204
+ ])
205
+ // Remove multiple items at once
206
+ await VenusApi.storage.removeMultipleItems(['playerData', 'settings'])
207
+ // Get all items from storage
208
+ await VenusApi.storage.getAllItems()
209
+ ```
210
+ ---
211
+
212
+ ### LLM API
213
+
214
+ ```typescript
215
+ // Request chat completion from AI model
216
+ const response = await VenusApi.ai.requestChatCompletionAsync({
217
+ model: 'chatGPT',
218
+ messages: [
219
+ {
220
+ role: 'user',
221
+ content: 'What is the best strategy for this level?'
222
+ }
223
+ ]
224
+ })
225
+
226
+ // Get available completion models
227
+ const models = await VenusApi.ai.getAvailableCompletionModels()
228
+ ```
35
229
 
36
230
  ### Simulation API
37
231
 
@@ -41,11 +235,11 @@ The Simulation API manages game state, recipe execution, and slot systems.
41
235
 
42
236
  ```typescript
43
237
  // Get current simulation state
44
- const state = await host.simulation.getStateAsync(roomId?)
238
+ const state = await VenusAPI.simulation.getStateAsync(roomId?)
45
239
  // Returns: { entities, inventory, currencies, timers, etc. }
46
240
 
47
241
  // Get simulation configuration
48
- const config = await host.simulation.getConfigAsync(roomId?)
242
+ const config = await VenusAPI.simulation.getConfigAsync(roomId?)
49
243
  ```
50
244
 
51
245
  #### Recipe Execution
@@ -54,51 +248,53 @@ Recipes are server-authoritative game actions (crafting, battles, upgrades, etc.
54
248
 
55
249
  ```typescript
56
250
  // Execute a recipe
57
- const result = await host.simulation.executeRecipeAsync(
251
+ const result = await VenusAPI.simulation.executeRecipeAsync(
58
252
  'craft_sword',
59
253
  { materials: ['iron', 'wood'] },
60
254
  { skipNotification: false }
61
255
  )
62
256
 
63
257
  // Execute a scoped recipe (entity-specific)
64
- const result = await host.simulation.executeScopedRecipeAsync(
258
+ const result = await VenusAPI.simulation.executeScopedRecipeAsync(
65
259
  'upgrade_weapon',
66
260
  'sword_123',
67
261
  { level: 5 }
68
262
  )
69
263
 
70
264
  // Get active recipe runs (for time-based recipes)
71
- const runs = await host.simulation.getActiveRunsAsync()
265
+ const runs = await VenusAPI.simulation.getActiveRunsAsync()
72
266
 
73
267
  // Collect completed recipe
74
- const result = await host.simulation.collectRecipeAsync(runId)
268
+ const result = await VenusAPI.simulation.collectRecipeAsync(runId)
75
269
 
76
270
  // Trigger recipe chain
77
- await host.simulation.triggerRecipeChainAsync('battle_complete')
271
+ await VenusAPI.simulation.triggerRecipeChainAsync('battle_complete')
78
272
  ```
79
273
 
80
274
  #### Recipe Requirements
81
275
 
82
276
  ```typescript
83
277
  // Check requirements for a single recipe
84
- const requirements = await host.simulation.getRecipeRequirementsAsync({
85
- recipeId: 'craft_sword',
86
- entity: 'player',
87
- amount: 1
88
- })
89
- // Returns: { canAfford, costs, rewards }
278
+ const requirements = await VenusAPI.simulation.getRecipeRequirementsAsync(
279
+ 'craft_sword',
280
+ 'player',
281
+ 1
282
+ )
283
+ // Returns: { recipeId, entity, amount?, inputs, canAfford, disabled }
90
284
 
91
285
  // Batch check multiple recipes
92
- const results = await host.simulation.getBatchRecipeRequirementsAsync([
93
- { recipeId: 'craft_sword', amount: 1 },
94
- { recipeId: 'craft_shield', amount: 2 }
286
+ const results = await VenusAPI.simulation.getBatchRecipeRequirementsAsync([
287
+ { recipeId: 'craft_sword', batchAmount: 1 },
288
+ { recipeId: 'craft_shield', batchAmount: 2 }
95
289
  ])
290
+ // Returns: { success, results, errors? }
96
291
 
97
292
  // Get available recipes
98
- const recipes = await host.simulation.getAvailableRecipesAsync({
293
+ const recipes = await VenusAPI.simulation.getAvailableRecipesAsync({
99
294
  roomId: 'room_123',
100
295
  includeActorRecipes: true
101
296
  })
297
+ // Returns: { success, recipes }
102
298
  ```
103
299
 
104
300
  #### Slot Management
@@ -107,24 +303,24 @@ Slots represent equipment, loadouts, teams, or any item container system:
107
303
 
108
304
  ```typescript
109
305
  // Get all slot containers
110
- const containers = await host.simulation.getSlotContainersAsync()
306
+ const containers = await VenusAPI.simulation.getSlotContainersAsync()
111
307
  // Returns: [{ id: 'equipment', slots: [...] }, { id: 'team', slots: [...] }]
112
308
 
113
309
  // Get slot assignments for a container
114
- const assignments = await host.simulation.getSlotAssignmentsAsync('equipment')
310
+ const assignments = await VenusAPI.simulation.getSlotAssignmentsAsync('equipment')
115
311
  // Returns: [{ slotId: 'weapon', itemId: 'sword_123' }, ...]
116
312
 
117
313
  // Assign item to slot
118
- await host.simulation.assignItemToSlotAsync('equipment', 'weapon', 'sword_123')
314
+ await VenusAPI.simulation.assignItemToSlotAsync('equipment', 'weapon', 'sword_123')
119
315
 
120
316
  // Remove item from slot
121
- await host.simulation.removeItemFromSlotAsync('equipment', 'weapon')
317
+ await VenusAPI.simulation.removeItemFromSlotAsync('equipment', 'weapon')
122
318
 
123
319
  // Get available items for a slot
124
- const items = await host.simulation.getAvailableItemsAsync('equipment', 'weapon')
320
+ const items = await VenusAPI.simulation.getAvailableItemsAsync('equipment', 'weapon')
125
321
 
126
322
  // Preview power calculation before assignment
127
- const preview = await host.simulation.calculatePowerPreviewAsync(
323
+ const preview = await VenusAPI.simulation.calculatePowerPreviewAsync(
128
324
  'equipment',
129
325
  'weapon',
130
326
  'sword_456'
@@ -132,7 +328,7 @@ const preview = await host.simulation.calculatePowerPreviewAsync(
132
328
  // Returns: { currentPower: 100, newPower: 150, delta: +50 }
133
329
 
134
330
  // Validate slot assignment
135
- const valid = await host.simulation.validateSlotAssignmentAsync(
331
+ const valid = await VenusAPI.simulation.validateSlotAssignmentAsync(
136
332
  'equipment',
137
333
  'weapon',
138
334
  'shield_123' // Wrong type
@@ -140,7 +336,7 @@ const valid = await host.simulation.validateSlotAssignmentAsync(
140
336
  // Returns: { valid: false, reason: 'Type mismatch' }
141
337
 
142
338
  // Batch operations (atomic)
143
- await host.simulation.executeBatchOperationsAsync([
339
+ await VenusAPI.simulation.executeBatchOperationsAsync([
144
340
  { type: 'assign', containerId: 'equipment', slotId: 'weapon', itemId: 'sword' },
145
341
  { type: 'assign', containerId: 'equipment', slotId: 'armor', itemId: 'plate' },
146
342
  { type: 'remove', containerId: 'equipment', slotId: 'boots' }
@@ -151,21 +347,22 @@ await host.simulation.executeBatchOperationsAsync([
151
347
 
152
348
  ```typescript
153
349
  // Resolve dynamic field values
154
- const value = await host.simulation.resolveFieldValueAsync(
350
+ const value = await VenusAPI.simulation.resolveFieldValueAsync(
155
351
  'player_123',
156
352
  'stats.power',
157
353
  'player'
158
354
  )
159
355
 
160
356
  // Get entity metadata
161
- const metadata = await host.simulation.getEntityMetadataAsync('sword_123')
357
+ const metadata = await VenusAPI.simulation.getEntityMetadataAsync('sword_123')
162
358
  ```
359
+ ---
163
360
 
164
361
  #### Utility Methods
165
362
 
166
363
  ```typescript
167
364
  // Sum stat contributions
168
- const totalPower = host.simulation.sumContributions(
365
+ const totalPower = VenusAPI.simulation.sumContributions(
169
366
  [{ power: 10 }, { power: 20 }, { power: 15 }],
170
367
  'power'
171
368
  )
@@ -180,20 +377,20 @@ Three-tier storage system with different data scopes:
180
377
 
181
378
  ```typescript
182
379
  // Device Cache - persists across all apps for the device
183
- await host.deviceCache.set('lastUserId', '12345')
184
- const userId = await host.deviceCache.get('lastUserId')
380
+ await VenusAPI.deviceCache.setItem('lastUserId', '12345')
381
+ const userId = await VenusAPI.deviceCache.getItem('lastUserId')
185
382
 
186
383
  // App Storage - app-specific persistent storage
187
- await host.appStorage.set('highScore', 1000)
188
- await host.appStorage.set('playerData', { level: 5, gold: 1000 })
384
+ await VenusAPI.appStorage.setItem('highScore', JSON.stringify(1000))
385
+ await VenusAPI.appStorage.setItem('playerData', JSON.stringify({ level: 5, gold: 1000 }))
189
386
 
190
387
  // Global Storage - shared across all apps for the user
191
- await host.globalStorage.set('preferences', { theme: 'dark' })
388
+ await VenusAPI.globalStorage.setItem('preferences', JSON.stringify({ theme: 'dark' }))
192
389
 
193
390
  // All storage APIs support:
194
- const value = await storage.get(key, defaultValue?)
195
- await storage.set(key, value)
196
- await storage.remove(key)
391
+ const value = await storage.getItem(key)
392
+ await storage.setItem(key, value)
393
+ await storage.removeItem(key)
197
394
  await storage.clear()
198
395
  const count = await storage.length()
199
396
  const keyName = await storage.key(index)
@@ -201,47 +398,6 @@ const keyName = await storage.key(index)
201
398
 
202
399
  ---
203
400
 
204
- ### Profile API
205
-
206
- ```typescript
207
- // Get current user profile
208
- const profile = await host.profile.getCurrentProfile()
209
- // Returns: { id, name, username }
210
- ```
211
-
212
- ---
213
-
214
- ### Ads API
215
-
216
- ```typescript
217
- // Check ad readiness
218
- const interstitialReady = await host.ads.isInterstitialReady()
219
- const rewardedReady = await host.ads.isRewardedReady()
220
-
221
- // Show interstitial ad
222
- await host.ads.showInterstitial()
223
-
224
- // Show rewarded video ad
225
- const watched = await host.ads.showRewarded()
226
- if (watched) {
227
- // User watched the full video, grant reward
228
- }
229
- ```
230
-
231
- ---
232
-
233
- ### Haptics API
234
-
235
- Trigger haptic feedback on supported devices:
236
-
237
- ```typescript
238
- // Available haptic types: 'light', 'medium', 'heavy', 'success', 'warning', 'error'
239
- await host.haptics.trigger('success')
240
- await host.haptics.trigger('warning')
241
- await host.haptics.trigger('heavy')
242
- ```
243
-
244
- ---
245
401
 
246
402
  ### Popups API
247
403
 
@@ -249,41 +405,42 @@ Display native-style UI popups:
249
405
 
250
406
  ```typescript
251
407
  // Toast messages
252
- await host.popups.showToast('Game saved!', {
408
+ await VenusAPI.popups.showToast('Game saved!', {
253
409
  duration: 3000,
254
410
  variant: 'success',
255
411
  action: { label: 'Undo' }
256
412
  })
257
413
 
258
414
  // Alert dialog
259
- await host.popups.showAlert({
260
- title: 'Warning',
261
- message: 'This action cannot be undone',
262
- buttonText: 'OK'
263
- })
415
+ await VenusAPI.popups.showAlert(
416
+ 'Warning',
417
+ 'This action cannot be undone',
418
+ { buttonText: 'OK' }
419
+ )
264
420
 
265
421
  // Confirm dialog
266
- const confirmed = await host.popups.showConfirm({
267
- title: 'Delete Item',
268
- message: 'Are you sure you want to delete this item?',
269
- confirmText: 'Delete',
270
- cancelText: 'Cancel'
271
- })
422
+ const confirmed = await VenusAPI.popups.showConfirm(
423
+ 'Delete Item',
424
+ 'Are you sure you want to delete this item?',
425
+ { confirmText: 'Delete', cancelText: 'Cancel' }
426
+ )
272
427
 
273
428
  if (confirmed) {
274
429
  // User confirmed
275
430
  }
276
431
 
277
432
  // Action sheet
278
- const selected = await host.popups.showActionSheet({
279
- title: 'Choose Action',
280
- options: [
281
- { id: 'edit', label: 'Edit', variant: 'default' },
282
- { id: 'share', label: 'Share', variant: 'default' },
283
- { id: 'delete', label: 'Delete', variant: 'destructive' }
433
+ const selected = await VenusAPI.popups.showActionSheet(
434
+ [
435
+ { id: 'edit', label: 'Edit' },
436
+ { id: 'share', label: 'Share' },
437
+ { id: 'delete', label: 'Delete' }
284
438
  ],
285
- cancelText: 'Cancel'
286
- })
439
+ {
440
+ title: 'Choose Action',
441
+ cancelButtonText: 'Cancel'
442
+ }
443
+ )
287
444
 
288
445
  if (selected === 'delete') {
289
446
  // User selected delete
@@ -297,18 +454,17 @@ if (selected === 'delete') {
297
454
  Stack-based navigation system:
298
455
 
299
456
  ```typescript
300
- // Get current stack information
301
- const stack = await host.navigation.getStackInfo()
302
- // Returns: { depth, currentApp, history }
457
+ // Get current stack information (synchronous)
458
+ const stack = VenusAPI.navigation.getStackInfo()
459
+ // Returns: { isInStack, stackPosition, isTopOfStack, stackDepth, parentInstanceId }
303
460
 
304
461
  // Push new app to stack
305
- await host.navigation.push({
306
- appId: 'bird-flap',
307
- context: { level: 5, difficulty: 'hard' }
462
+ await VenusAPI.navigation.pushApp('bird-flap', {
463
+ contextData: { level: 5, difficulty: 'hard' }
308
464
  })
309
465
 
310
466
  // Pop from stack (returns to previous app)
311
- await host.navigation.pop()
467
+ await VenusAPI.navigation.popApp()
312
468
  ```
313
469
 
314
470
  ---
@@ -319,48 +475,27 @@ Social interaction APIs for posts:
319
475
 
320
476
  ```typescript
321
477
  // Get post interaction data
322
- const interactions = await host.post.getInteractions()
323
- // Returns: { postId, isLiked, isFollowing, likeCount, commentCount }
478
+ const postInfo = await VenusAPI.post.getPostInfo()
479
+ // Returns: { isLiked, isFollowing, likesCount, commentsCount }
324
480
 
325
481
  // Toggle like
326
- await host.post.toggleLike()
482
+ const likeResult = await VenusAPI.post.toggleLikeAsync()
483
+ // Returns: { isLiked, likesCount, action: 'liked' | 'unliked' }
327
484
 
328
485
  // Toggle follow
329
- await host.post.toggleFollow()
486
+ const followResult = await VenusAPI.post.toggleFollowAsync()
487
+ // Returns: { isFollowing, action: 'followed' | 'unfollowed' }
330
488
 
331
489
  // Open comments UI
332
- await host.post.openComments()
490
+ const commentsResult = await VenusAPI.post.openCommentsAsync()
491
+ // Returns: { opened, commentsCount }
333
492
 
334
493
  // Share post
335
- await host.post.share({
494
+ const shareResult = await VenusAPI.post.sharePostAsync({
336
495
  message: 'Check this out!',
337
- recipientIds: ['user1', 'user2']
496
+ title: 'My Post'
338
497
  })
339
- ```
340
-
341
- ---
342
-
343
- ### AI API
344
-
345
- LLM integration for chat completions:
346
-
347
- ```typescript
348
- // Get available models
349
- const models = await host.ai.getAvailableModels()
350
- // Returns: ['gpt-4', 'gpt-3.5-turbo', 'claude-3-opus', ...]
351
-
352
- // Chat completion
353
- const response = await host.ai.chatCompletion({
354
- messages: [
355
- { role: 'system', content: 'You are a helpful game assistant' },
356
- { role: 'user', content: 'What is the best strategy for this level?' }
357
- ],
358
- model: 'gpt-4',
359
- temperature: 0.7,
360
- max_tokens: 500
361
- })
362
-
363
- console.log(response.choices[0].message.content)
498
+ // Returns: { shared, platform, customMessage? }
364
499
  ```
365
500
 
366
501
  ---
@@ -369,14 +504,14 @@ console.log(response.choices[0].message.content)
369
504
 
370
505
  ```typescript
371
506
  // Log custom event
372
- await host.analytics.logEvent('level_complete', {
507
+ await VenusAPI.analytics.logEvent('level_complete', {
373
508
  level: 5,
374
509
  score: 1000,
375
510
  timeElapsed: 120
376
511
  })
377
512
 
378
513
  // Set user properties
379
- await host.analytics.setUserProperty('vip_status', 'gold')
514
+ await VenusAPI.analytics.setUserProperty('vip_status', 'gold')
380
515
  ```
381
516
 
382
517
  ---
@@ -384,27 +519,32 @@ await host.analytics.setUserProperty('vip_status', 'gold')
384
519
  ### Avatar 3D API
385
520
 
386
521
  ```typescript
387
- // Get current avatar configuration
388
- const avatar = await host.avatar3d.get()
522
+ // Load current avatar configuration
523
+ const avatar = await VenusAPI.avatar3d.loadAvatar()
524
+ // Or load a specific avatar
525
+ const avatarConfig = await VenusAPI.avatar3d.loadAvatar('avatar_123')
389
526
 
390
527
  // Show avatar editor
391
- const result = await host.avatar3d.showEditor({
392
- allowSave: true,
393
- enableSharing: true
528
+ const result = await VenusAPI.avatar3d.showEditor({
529
+ currentAvatar: avatarConfig,
530
+ contextData: { source: 'settings' }
394
531
  })
395
532
 
396
- if (result.saved) {
397
- console.log('Avatar updated:', result.avatarId)
533
+ if (result.wasChanged && result.savedAvatarId) {
534
+ console.log('Avatar updated:', result.savedAvatarId)
398
535
  }
399
536
 
400
- // Delete avatar
401
- await host.avatar3d.delete()
537
+ // Save avatar
538
+ const avatarId = await VenusAPI.avatar3d.saveAvatar(avatarConfig)
402
539
 
403
- // Get shared avatar
404
- const sharedAvatar = await host.avatar3d.getSharedAvatar('avatar_123')
540
+ // Delete avatar
541
+ await VenusAPI.avatar3d.deleteAvatar()
405
542
 
406
543
  // Download avatar manifest
407
- const manifest = await host.avatar3d.downloadManifest('avatar_123')
544
+ const manifest = await VenusAPI.avatar3d.downloadManifest()
545
+
546
+ // Download asset paths
547
+ const assetPaths = await VenusAPI.avatar3d.downloadAssetPaths()
408
548
  ```
409
549
 
410
550
  ---
@@ -415,17 +555,17 @@ Multi-user room management:
415
555
 
416
556
  ```typescript
417
557
  // Get current room
418
- const room = await host.rooms.getCurrentRoom()
558
+ const room = await VenusAPI.rooms.getCurrentRoom()
419
559
  // Returns: { id, name, participants, metadata }
420
560
 
421
561
  // Join room
422
- await host.rooms.join('room_123')
562
+ await VenusAPI.rooms.join('room_123')
423
563
 
424
564
  // Leave room
425
- await host.rooms.leave()
565
+ await VenusAPI.rooms.leave()
426
566
 
427
567
  // Send room message
428
- await host.rooms.sendMessage({
568
+ await VenusAPI.rooms.sendMessage({
429
569
  type: 'game_action',
430
570
  data: { action: 'move', x: 10, y: 20 }
431
571
  })
@@ -433,55 +573,34 @@ await host.rooms.sendMessage({
433
573
 
434
574
  ---
435
575
 
436
- ### Notifications API
437
-
438
- Local push notifications:
439
-
440
- ```typescript
441
- // Schedule notification
442
- await host.notifications.schedule({
443
- id: 'energy_full',
444
- title: 'Energy Restored!',
445
- body: 'Your energy is now full. Come back to play!',
446
- trigger: { type: 'time', seconds: 3600 } // 1 hour
447
- })
448
-
449
- // Cancel notification
450
- await host.notifications.cancel('energy_full')
451
-
452
- // Get all scheduled notifications
453
- const scheduled = await host.notifications.getAllScheduled()
454
-
455
- // Check if notifications are enabled
456
- const enabled = await host.notifications.isEnabled()
457
-
458
- // Enable/disable notifications
459
- await host.notifications.setEnabled(true)
460
- ```
461
-
462
- ---
463
-
464
576
  ### Time API
465
577
 
466
578
  Server time synchronization and formatting:
467
579
 
468
580
  ```typescript
469
581
  // Get server time
470
- const serverTime = await host.time.getServerTime()
471
- // Returns: { timestamp, timezone, formatted }
582
+ const serverTimeData = await VenusAPI.time.requestTimeAsync()
583
+ // Returns: { serverTime, localTime, timezoneOffset, formattedTime, locale }
472
584
 
473
585
  // Format time with locale
474
- const formatted = host.time.format(Date.now(), {
586
+ const formatted = VenusAPI.time.formatTime(Date.now(), {
475
587
  locale: 'en-US',
476
588
  format: 'full' // 'full', 'long', 'medium', 'short'
477
589
  })
478
590
 
479
591
  // Format number with locale
480
- const formatted = host.time.formatNumber(1234567.89, {
592
+ const formattedNumber = VenusAPI.time.formatNumber(1234567.89, {
481
593
  locale: 'en-US',
482
594
  style: 'currency',
483
595
  currency: 'USD'
484
596
  })
597
+
598
+ // Get future time
599
+ const futureTime = await VenusAPI.time.getFutureTimeAsync({
600
+ days: 1,
601
+ hours: 2,
602
+ minutes: 30
603
+ })
485
604
  ```
486
605
 
487
606
  ---
@@ -489,11 +608,17 @@ const formatted = host.time.formatNumber(1234567.89, {
489
608
  ### CDN API
490
609
 
491
610
  ```typescript
492
- // Get CDN URL for an asset
493
- const url = await host.cdn.getAssetUrl('images/logo.png')
611
+ // Resolve asset URLs (synchronous)
612
+ const assetUrl = VenusAPI.cdn.resolveAssetUrl('images/logo.png')
613
+ const avatarUrl = VenusAPI.cdn.resolveAvatarAssetUrl('avatars/model.glb')
614
+ const libUrl = VenusAPI.cdn.resolveSharedLibUrl('libs/helper.js')
615
+
616
+ // Get CDN base URL
617
+ const baseUrl = VenusAPI.cdn.getAssetCdnBaseUrl()
494
618
 
495
- // Upload to CDN
496
- const uploadUrl = await host.cdn.upload(file)
619
+ // Fetch from CDN
620
+ const response = await VenusAPI.cdn.fetchFromCdn('https://cdn.example.com/file.json')
621
+ const blob = await VenusAPI.cdn.fetchBlob('path/to/asset.png')
497
622
  ```
498
623
 
499
624
  ---
@@ -503,78 +628,53 @@ const uploadUrl = await host.cdn.upload(file)
503
628
  Feature flags, experiments, and A/B testing:
504
629
 
505
630
  ```typescript
506
- // Get feature flag value
507
- const enabled = await host.features.getFeatureFlag('new_ui_enabled')
631
+ // Get feature flag value (returns boolean)
632
+ const enabled = await VenusAPI.features.getFeatureFlag('new_ui_enabled')
508
633
 
509
- // Get feature gate (boolean flag)
510
- const canAccess = await host.features.getFeatureGate('beta_features')
634
+ // Get feature gate (returns boolean)
635
+ const canAccess = await VenusAPI.features.getFeatureGate('beta_features')
511
636
 
512
637
  // Get experiment variant
513
- const experiment = await host.features.getExperiment('checkout_flow')
514
- // Returns: { variant: 'control' | 'variant_a' | 'variant_b', ... }
515
- ```
516
-
517
- ---
518
-
519
- ### IAP API
520
-
521
- In-app purchases and virtual currency:
522
-
523
- ```typescript
524
- // Get wallet balance
525
- const wallet = await host.iap.getWallet()
526
- // Returns: { coins: 1000, gems: 50 }
527
-
528
- // Spend currency
529
- const result = await host.iap.spendCurrency('coins', 100)
530
- if (result.success) {
531
- console.log('Purchase successful')
532
- }
533
-
534
- // Listen for wallet updates
535
- host.iap.onWalletUpdate((wallet) => {
536
- console.log('Wallet updated:', wallet)
537
- })
638
+ const experiment = await VenusAPI.features.getExperiment('checkout_flow')
639
+ // Returns: { name, ruleID, value, groupName } | null
538
640
  ```
539
641
 
540
- ---
541
-
542
642
  ### Lifecycle API
543
643
 
544
644
  App lifecycle event handlers:
545
645
 
546
646
  ```typescript
547
647
  // Register lifecycle callbacks
548
- host.lifecycle.onReady(() => {
648
+ VenusAPI.lifecycle.onReady(() => {
549
649
  console.log('App ready')
550
650
  })
551
651
 
552
- host.lifecycle.onShow((context) => {
652
+ VenusAPI.lifecycle.onShow((context) => {
553
653
  console.log('App shown', context.hudInsets)
554
654
  })
555
655
 
556
- host.lifecycle.onPlay((context) => {
656
+ VenusAPI.lifecycle.onPlay((context) => {
557
657
  console.log('App playing', context.hudInsets)
558
658
  })
559
659
 
560
- host.lifecycle.onPause(() => {
660
+ VenusAPI.lifecycle.onPause(() => {
561
661
  console.log('App paused')
562
662
  })
563
663
 
564
- host.lifecycle.onResume(() => {
664
+ VenusAPI.lifecycle.onResume(() => {
565
665
  console.log('App resumed')
566
666
  })
567
667
 
568
- host.lifecycle.onHidden(() => {
668
+ VenusAPI.lifecycle.onHidden(() => {
569
669
  console.log('App hidden')
570
670
  })
571
671
 
572
- host.lifecycle.onQuit(() => {
672
+ VenusAPI.lifecycle.onQuit(() => {
573
673
  console.log('App quitting')
574
674
  })
575
675
 
576
676
  // Quit the app
577
- await host.lifecycle.quit()
677
+ await VenusAPI.lifecycle.quit()
578
678
  ```
579
679
 
580
680
  ---
@@ -583,9 +683,9 @@ await host.lifecycle.quit()
583
683
 
584
684
  ```typescript
585
685
  // Log messages
586
- host.logging.log('Info message', { data: 'value' })
587
- host.logging.error('Error message', error)
588
- host.logging.debug('Debug info')
686
+ VenusAPI.logging.log('Info message', { data: 'value' })
687
+ VenusAPI.logging.error('Error message', error)
688
+ VenusAPI.logging.debug('Debug info')
589
689
  ```
590
690
 
591
691
  ---
@@ -595,22 +695,18 @@ host.logging.debug('Debug info')
595
695
  All APIs have complete mock implementations for local development:
596
696
 
597
697
  ```typescript
598
- import { createHost, VenusAPI } from 'venus-sdk'
599
-
600
- const venusApi = new VenusAPI()
601
- await venusApi.initializeAsync({ mock: true })
698
+ import { default as VenusAPI } from '@series-inc/venus-sdk/api'
602
699
 
603
- const host = createHost(venusApi, true) // true = mock mode
604
- await host.initialize()
700
+ await VenusAPI.initializeAsync({ mock: true })
605
701
 
606
702
  // All APIs work the same, but with simulated responses
607
- const state = await host.simulation.getStateAsync()
703
+ const state = await VenusAPI.simulation.getStateAsync()
608
704
  ```
609
705
 
610
706
  ### Custom Mock Data
611
707
 
612
708
  ```typescript
613
- await venusApi.initializeAsync({
709
+ await VenusAPI.initializeAsync({
614
710
  mock: {
615
711
  simulation: {
616
712
  state: { customData: 'value' }