@series-inc/venus-sdk 3.0.4 → 3.0.6
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 +14 -979
- package/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-CIXV8I_p.d.mts} +389 -186
- package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-CIXV8I_p.d.ts} +389 -186
- package/dist/{chunk-PXWCNWJ6.mjs → chunk-LBJFUHOH.mjs} +948 -1370
- package/dist/chunk-LBJFUHOH.mjs.map +1 -0
- package/dist/{chunk-W7IPHM67.mjs → chunk-MWUS3A7C.mjs} +3 -22
- package/dist/chunk-MWUS3A7C.mjs.map +1 -0
- package/dist/core-RDMPQV6U.mjs +3 -0
- package/dist/{core-R3FHW62G.mjs.map → core-RDMPQV6U.mjs.map} +1 -1
- package/dist/index.cjs +944 -1386
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +142 -79
- package/dist/index.d.ts +142 -79
- package/dist/index.mjs +2 -6
- package/dist/index.mjs.map +1 -1
- package/dist/venus-api/index.cjs +1010 -1717
- package/dist/venus-api/index.cjs.map +1 -1
- package/dist/venus-api/index.d.mts +2 -2
- package/dist/venus-api/index.d.ts +2 -2
- package/dist/venus-api/index.mjs +43 -308
- package/dist/venus-api/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-PXWCNWJ6.mjs.map +0 -1
- package/dist/chunk-W7IPHM67.mjs.map +0 -1
- package/dist/core-R3FHW62G.mjs +0 -3
package/README.md
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
# Venus SDK API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build connected HTML5 games that integrate deeply with the Venus platform. This package provides the client SDK used by hosted games as well as the local mock environment for development.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Highlights
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```
|
|
7
|
+
- Typed APIs for Venus platform services (simulation, rooms, analytics, ads, and more)
|
|
8
|
+
- Host-aware tooling including lifecycle hooks, safe-area utilities, and asset loading helpers
|
|
10
9
|
|
|
11
|
-
##
|
|
10
|
+
## Quick Start
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
### Installation
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- **Venus API** - Low-level platform interface
|
|
14
|
+
```bash
|
|
15
|
+
npm install @series-inc/venus-sdk@latest
|
|
16
|
+
```
|
|
19
17
|
|
|
20
|
-
###
|
|
18
|
+
### Initialize
|
|
21
19
|
|
|
22
20
|
```typescript
|
|
23
21
|
import { default as VenusAPI } from '@series-inc/venus-sdk/api'
|
|
@@ -26,973 +24,10 @@ import { default as VenusAPI } from '@series-inc/venus-sdk/api'
|
|
|
26
24
|
await VenusAPI.initializeAsync()
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
##
|
|
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()
|
|
74
|
-
|
|
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
|
-
}
|
|
86
|
-
```
|
|
87
|
-
---
|
|
88
|
-
|
|
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
|
-
```
|
|
229
|
-
|
|
230
|
-
### Simulation API
|
|
231
|
-
|
|
232
|
-
The Simulation API manages game state, recipe execution, and slot systems.
|
|
233
|
-
|
|
234
|
-
#### State Management
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
// Get current simulation state
|
|
238
|
-
const state = await VenusAPI.simulation.getStateAsync(roomId?)
|
|
239
|
-
// Returns: { entities, inventory, currencies, timers, etc. }
|
|
240
|
-
|
|
241
|
-
// Get simulation configuration
|
|
242
|
-
const config = await VenusAPI.simulation.getConfigAsync(roomId?)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
#### Recipe Execution
|
|
246
|
-
|
|
247
|
-
Recipes are server-authoritative game actions (crafting, battles, upgrades, etc.):
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// Execute a recipe
|
|
251
|
-
const result = await VenusAPI.simulation.executeRecipeAsync(
|
|
252
|
-
'craft_sword',
|
|
253
|
-
{ materials: ['iron', 'wood'] },
|
|
254
|
-
{ skipNotification: false }
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
// Execute a scoped recipe (entity-specific)
|
|
258
|
-
const result = await VenusAPI.simulation.executeScopedRecipeAsync(
|
|
259
|
-
'upgrade_weapon',
|
|
260
|
-
'sword_123',
|
|
261
|
-
{ level: 5 }
|
|
262
|
-
)
|
|
263
|
-
|
|
264
|
-
// Get active recipe runs (for time-based recipes)
|
|
265
|
-
const runs = await VenusAPI.simulation.getActiveRunsAsync()
|
|
266
|
-
|
|
267
|
-
// Collect completed recipe
|
|
268
|
-
const result = await VenusAPI.simulation.collectRecipeAsync(runId)
|
|
269
|
-
|
|
270
|
-
// Trigger recipe chain
|
|
271
|
-
await VenusAPI.simulation.triggerRecipeChainAsync('battle_complete')
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
#### Recipe Requirements
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
// Check requirements for a single recipe
|
|
278
|
-
const requirements = await VenusAPI.simulation.getRecipeRequirementsAsync(
|
|
279
|
-
'craft_sword',
|
|
280
|
-
'player',
|
|
281
|
-
1
|
|
282
|
-
)
|
|
283
|
-
// Returns: { recipeId, entity, amount?, inputs, canAfford, disabled }
|
|
284
|
-
|
|
285
|
-
// Batch check multiple recipes
|
|
286
|
-
const results = await VenusAPI.simulation.getBatchRecipeRequirementsAsync([
|
|
287
|
-
{ recipeId: 'craft_sword', batchAmount: 1 },
|
|
288
|
-
{ recipeId: 'craft_shield', batchAmount: 2 }
|
|
289
|
-
])
|
|
290
|
-
// Returns: { success, results, errors? }
|
|
291
|
-
|
|
292
|
-
// Get available recipes
|
|
293
|
-
const recipes = await VenusAPI.simulation.getAvailableRecipesAsync({
|
|
294
|
-
roomId: 'room_123',
|
|
295
|
-
includeActorRecipes: true
|
|
296
|
-
})
|
|
297
|
-
// Returns: { success, recipes }
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
#### Slot Management
|
|
301
|
-
|
|
302
|
-
Slots represent equipment, loadouts, teams, or any item container system:
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
// Get all slot containers
|
|
306
|
-
const containers = await VenusAPI.simulation.getSlotContainersAsync()
|
|
307
|
-
// Returns: [{ id: 'equipment', slots: [...] }, { id: 'team', slots: [...] }]
|
|
308
|
-
|
|
309
|
-
// Get slot assignments for a container
|
|
310
|
-
const assignments = await VenusAPI.simulation.getSlotAssignmentsAsync('equipment')
|
|
311
|
-
// Returns: [{ slotId: 'weapon', itemId: 'sword_123' }, ...]
|
|
312
|
-
|
|
313
|
-
// Assign item to slot
|
|
314
|
-
await VenusAPI.simulation.assignItemToSlotAsync('equipment', 'weapon', 'sword_123')
|
|
315
|
-
|
|
316
|
-
// Remove item from slot
|
|
317
|
-
await VenusAPI.simulation.removeItemFromSlotAsync('equipment', 'weapon')
|
|
318
|
-
|
|
319
|
-
// Get available items for a slot
|
|
320
|
-
const items = await VenusAPI.simulation.getAvailableItemsAsync('equipment', 'weapon')
|
|
321
|
-
|
|
322
|
-
// Preview power calculation before assignment
|
|
323
|
-
const preview = await VenusAPI.simulation.calculatePowerPreviewAsync(
|
|
324
|
-
'equipment',
|
|
325
|
-
'weapon',
|
|
326
|
-
'sword_456'
|
|
327
|
-
)
|
|
328
|
-
// Returns: { currentPower: 100, newPower: 150, delta: +50 }
|
|
329
|
-
|
|
330
|
-
// Validate slot assignment
|
|
331
|
-
const valid = await VenusAPI.simulation.validateSlotAssignmentAsync(
|
|
332
|
-
'equipment',
|
|
333
|
-
'weapon',
|
|
334
|
-
'shield_123' // Wrong type
|
|
335
|
-
)
|
|
336
|
-
// Returns: { valid: false, reason: 'Type mismatch' }
|
|
337
|
-
|
|
338
|
-
// Batch operations (atomic)
|
|
339
|
-
await VenusAPI.simulation.executeBatchOperationsAsync([
|
|
340
|
-
{ type: 'assign', containerId: 'equipment', slotId: 'weapon', itemId: 'sword' },
|
|
341
|
-
{ type: 'assign', containerId: 'equipment', slotId: 'armor', itemId: 'plate' },
|
|
342
|
-
{ type: 'remove', containerId: 'equipment', slotId: 'boots' }
|
|
343
|
-
], false) // false = execute, true = validate only
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Field Resolution & Metadata
|
|
347
|
-
|
|
348
|
-
```typescript
|
|
349
|
-
// Resolve dynamic field values
|
|
350
|
-
const value = await VenusAPI.simulation.resolveFieldValueAsync(
|
|
351
|
-
'player_123',
|
|
352
|
-
'stats.power',
|
|
353
|
-
'player'
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
// Get entity metadata
|
|
357
|
-
const metadata = await VenusAPI.simulation.getEntityMetadataAsync('sword_123')
|
|
358
|
-
```
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
#### Utility Methods
|
|
362
|
-
|
|
363
|
-
```typescript
|
|
364
|
-
// Sum stat contributions
|
|
365
|
-
const totalPower = VenusAPI.simulation.sumContributions(
|
|
366
|
-
[{ power: 10 }, { power: 20 }, { power: 15 }],
|
|
367
|
-
'power'
|
|
368
|
-
)
|
|
369
|
-
// Returns: 45
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
---
|
|
373
|
-
|
|
374
|
-
### Storage API
|
|
375
|
-
|
|
376
|
-
Three-tier storage system with different data scopes:
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
// Device Cache - persists across all apps for the device
|
|
380
|
-
await VenusAPI.deviceCache.setItem('lastUserId', '12345')
|
|
381
|
-
const userId = await VenusAPI.deviceCache.getItem('lastUserId')
|
|
382
|
-
|
|
383
|
-
// App Storage - app-specific persistent storage
|
|
384
|
-
await VenusAPI.appStorage.setItem('highScore', JSON.stringify(1000))
|
|
385
|
-
await VenusAPI.appStorage.setItem('playerData', JSON.stringify({ level: 5, gold: 1000 }))
|
|
386
|
-
|
|
387
|
-
// Global Storage - shared across all apps for the user
|
|
388
|
-
await VenusAPI.globalStorage.setItem('preferences', JSON.stringify({ theme: 'dark' }))
|
|
389
|
-
|
|
390
|
-
// All storage APIs support:
|
|
391
|
-
const value = await storage.getItem(key)
|
|
392
|
-
await storage.setItem(key, value)
|
|
393
|
-
await storage.removeItem(key)
|
|
394
|
-
await storage.clear()
|
|
395
|
-
const count = await storage.length()
|
|
396
|
-
const keyName = await storage.key(index)
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
---
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
### Popups API
|
|
403
|
-
|
|
404
|
-
Display native-style UI popups:
|
|
405
|
-
|
|
406
|
-
```typescript
|
|
407
|
-
// Toast messages
|
|
408
|
-
await VenusAPI.popups.showToast('Game saved!', {
|
|
409
|
-
duration: 3000,
|
|
410
|
-
variant: 'success',
|
|
411
|
-
action: { label: 'Undo' }
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
// Alert dialog
|
|
415
|
-
await VenusAPI.popups.showAlert(
|
|
416
|
-
'Warning',
|
|
417
|
-
'This action cannot be undone',
|
|
418
|
-
{ buttonText: 'OK' }
|
|
419
|
-
)
|
|
420
|
-
|
|
421
|
-
// Confirm dialog
|
|
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
|
-
)
|
|
427
|
-
|
|
428
|
-
if (confirmed) {
|
|
429
|
-
// User confirmed
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Action sheet
|
|
433
|
-
const selected = await VenusAPI.popups.showActionSheet(
|
|
434
|
-
[
|
|
435
|
-
{ id: 'edit', label: 'Edit' },
|
|
436
|
-
{ id: 'share', label: 'Share' },
|
|
437
|
-
{ id: 'delete', label: 'Delete' }
|
|
438
|
-
],
|
|
439
|
-
{
|
|
440
|
-
title: 'Choose Action',
|
|
441
|
-
cancelButtonText: 'Cancel'
|
|
442
|
-
}
|
|
443
|
-
)
|
|
444
|
-
|
|
445
|
-
if (selected === 'delete') {
|
|
446
|
-
// User selected delete
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
### Navigation API
|
|
453
|
-
|
|
454
|
-
Stack-based navigation system:
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
// Get current stack information (synchronous)
|
|
458
|
-
const stack = VenusAPI.navigation.getStackInfo()
|
|
459
|
-
// Returns: { isInStack, stackPosition, isTopOfStack, stackDepth, parentInstanceId }
|
|
460
|
-
|
|
461
|
-
// Push new app to stack
|
|
462
|
-
await VenusAPI.navigation.pushApp('bird-flap', {
|
|
463
|
-
contextData: { level: 5, difficulty: 'hard' }
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
// Pop from stack (returns to previous app)
|
|
467
|
-
await VenusAPI.navigation.popApp()
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
---
|
|
471
|
-
|
|
472
|
-
### Post API
|
|
473
|
-
|
|
474
|
-
Social interaction APIs for posts:
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
// Get post interaction data
|
|
478
|
-
const postInfo = await VenusAPI.post.getPostInfo()
|
|
479
|
-
// Returns: { isLiked, isFollowing, likesCount, commentsCount }
|
|
480
|
-
|
|
481
|
-
// Toggle like
|
|
482
|
-
const likeResult = await VenusAPI.post.toggleLikeAsync()
|
|
483
|
-
// Returns: { isLiked, likesCount, action: 'liked' | 'unliked' }
|
|
484
|
-
|
|
485
|
-
// Toggle follow
|
|
486
|
-
const followResult = await VenusAPI.post.toggleFollowAsync()
|
|
487
|
-
// Returns: { isFollowing, action: 'followed' | 'unfollowed' }
|
|
488
|
-
|
|
489
|
-
// Open comments UI
|
|
490
|
-
const commentsResult = await VenusAPI.post.openCommentsAsync()
|
|
491
|
-
// Returns: { opened, commentsCount }
|
|
492
|
-
|
|
493
|
-
// Share post
|
|
494
|
-
const shareResult = await VenusAPI.post.sharePostAsync({
|
|
495
|
-
message: 'Check this out!',
|
|
496
|
-
title: 'My Post'
|
|
497
|
-
})
|
|
498
|
-
// Returns: { shared, platform, customMessage? }
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
---
|
|
502
|
-
|
|
503
|
-
### Analytics API
|
|
504
|
-
|
|
505
|
-
```typescript
|
|
506
|
-
// Log custom event
|
|
507
|
-
await VenusAPI.analytics.logEvent('level_complete', {
|
|
508
|
-
level: 5,
|
|
509
|
-
score: 1000,
|
|
510
|
-
timeElapsed: 120
|
|
511
|
-
})
|
|
512
|
-
|
|
513
|
-
// Set user properties
|
|
514
|
-
await VenusAPI.analytics.setUserProperty('vip_status', 'gold')
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
---
|
|
518
|
-
|
|
519
|
-
### Avatar 3D API
|
|
520
|
-
|
|
521
|
-
```typescript
|
|
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')
|
|
526
|
-
|
|
527
|
-
// Show avatar editor
|
|
528
|
-
const result = await VenusAPI.avatar3d.showEditor({
|
|
529
|
-
currentAvatar: avatarConfig,
|
|
530
|
-
contextData: { source: 'settings' }
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
if (result.wasChanged && result.savedAvatarId) {
|
|
534
|
-
console.log('Avatar updated:', result.savedAvatarId)
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// Save avatar
|
|
538
|
-
const avatarId = await VenusAPI.avatar3d.saveAvatar(avatarConfig)
|
|
539
|
-
|
|
540
|
-
// Delete avatar
|
|
541
|
-
await VenusAPI.avatar3d.deleteAvatar()
|
|
542
|
-
|
|
543
|
-
// Download avatar manifest
|
|
544
|
-
const manifest = await VenusAPI.avatar3d.downloadManifest()
|
|
545
|
-
|
|
546
|
-
// Download asset paths
|
|
547
|
-
const assetPaths = await VenusAPI.avatar3d.downloadAssetPaths()
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
---
|
|
551
|
-
|
|
552
|
-
### Rooms API
|
|
553
|
-
|
|
554
|
-
Multi-user room management:
|
|
555
|
-
|
|
556
|
-
```typescript
|
|
557
|
-
// Get current room
|
|
558
|
-
const room = await VenusAPI.rooms.getCurrentRoom()
|
|
559
|
-
// Returns: { id, name, participants, metadata }
|
|
560
|
-
|
|
561
|
-
// Join room
|
|
562
|
-
await VenusAPI.rooms.join('room_123')
|
|
563
|
-
|
|
564
|
-
// Leave room
|
|
565
|
-
await VenusAPI.rooms.leave()
|
|
566
|
-
|
|
567
|
-
// Send room message
|
|
568
|
-
await VenusAPI.rooms.sendMessage({
|
|
569
|
-
type: 'game_action',
|
|
570
|
-
data: { action: 'move', x: 10, y: 20 }
|
|
571
|
-
})
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
---
|
|
575
|
-
|
|
576
|
-
### Time API
|
|
577
|
-
|
|
578
|
-
Server time synchronization and formatting:
|
|
579
|
-
|
|
580
|
-
```typescript
|
|
581
|
-
// Get server time
|
|
582
|
-
const serverTimeData = await VenusAPI.time.requestTimeAsync()
|
|
583
|
-
// Returns: { serverTime, localTime, timezoneOffset, formattedTime, locale }
|
|
584
|
-
|
|
585
|
-
// Format time with locale
|
|
586
|
-
const formatted = VenusAPI.time.formatTime(Date.now(), {
|
|
587
|
-
locale: 'en-US',
|
|
588
|
-
format: 'full' // 'full', 'long', 'medium', 'short'
|
|
589
|
-
})
|
|
590
|
-
|
|
591
|
-
// Format number with locale
|
|
592
|
-
const formattedNumber = VenusAPI.time.formatNumber(1234567.89, {
|
|
593
|
-
locale: 'en-US',
|
|
594
|
-
style: 'currency',
|
|
595
|
-
currency: 'USD'
|
|
596
|
-
})
|
|
597
|
-
|
|
598
|
-
// Get future time
|
|
599
|
-
const futureTime = await VenusAPI.time.getFutureTimeAsync({
|
|
600
|
-
days: 1,
|
|
601
|
-
hours: 2,
|
|
602
|
-
minutes: 30
|
|
603
|
-
})
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
---
|
|
607
|
-
|
|
608
|
-
### CDN API
|
|
609
|
-
|
|
610
|
-
```typescript
|
|
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()
|
|
618
|
-
|
|
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')
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
---
|
|
625
|
-
|
|
626
|
-
### Features API
|
|
627
|
-
|
|
628
|
-
Feature flags, experiments, and A/B testing:
|
|
629
|
-
|
|
630
|
-
```typescript
|
|
631
|
-
// Get feature flag value (returns boolean)
|
|
632
|
-
const enabled = await VenusAPI.features.getFeatureFlag('new_ui_enabled')
|
|
633
|
-
|
|
634
|
-
// Get feature gate (returns boolean)
|
|
635
|
-
const canAccess = await VenusAPI.features.getFeatureGate('beta_features')
|
|
636
|
-
|
|
637
|
-
// Get experiment variant
|
|
638
|
-
const experiment = await VenusAPI.features.getExperiment('checkout_flow')
|
|
639
|
-
// Returns: { name, ruleID, value, groupName } | null
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
### Lifecycle API
|
|
643
|
-
|
|
644
|
-
App lifecycle event handlers:
|
|
645
|
-
|
|
646
|
-
```typescript
|
|
647
|
-
// Register lifecycle callbacks
|
|
648
|
-
VenusAPI.lifecycle.onReady(() => {
|
|
649
|
-
console.log('App ready')
|
|
650
|
-
})
|
|
651
|
-
|
|
652
|
-
VenusAPI.lifecycle.onShow((context) => {
|
|
653
|
-
console.log('App shown', context.hudInsets)
|
|
654
|
-
})
|
|
655
|
-
|
|
656
|
-
VenusAPI.lifecycle.onPlay((context) => {
|
|
657
|
-
console.log('App playing', context.hudInsets)
|
|
658
|
-
})
|
|
659
|
-
|
|
660
|
-
VenusAPI.lifecycle.onPause(() => {
|
|
661
|
-
console.log('App paused')
|
|
662
|
-
})
|
|
663
|
-
|
|
664
|
-
VenusAPI.lifecycle.onResume(() => {
|
|
665
|
-
console.log('App resumed')
|
|
666
|
-
})
|
|
667
|
-
|
|
668
|
-
VenusAPI.lifecycle.onHidden(() => {
|
|
669
|
-
console.log('App hidden')
|
|
670
|
-
})
|
|
671
|
-
|
|
672
|
-
VenusAPI.lifecycle.onQuit(() => {
|
|
673
|
-
console.log('App quitting')
|
|
674
|
-
})
|
|
675
|
-
|
|
676
|
-
// Quit the app
|
|
677
|
-
await VenusAPI.lifecycle.quit()
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
---
|
|
681
|
-
|
|
682
|
-
### Logging API
|
|
683
|
-
|
|
684
|
-
```typescript
|
|
685
|
-
// Log messages
|
|
686
|
-
VenusAPI.logging.log('Info message', { data: 'value' })
|
|
687
|
-
VenusAPI.logging.error('Error message', error)
|
|
688
|
-
VenusAPI.logging.debug('Debug info')
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
---
|
|
692
|
-
|
|
693
|
-
### Leaderboard API (BETA)
|
|
694
|
-
|
|
695
|
-
Competitive leaderboards with anti-cheat, multiple modes, and time periods.
|
|
696
|
-
|
|
697
|
-
#### API Methods
|
|
698
|
-
|
|
699
|
-
```typescript
|
|
700
|
-
// Start a leaderboard session
|
|
701
|
-
const session = await VenusAPI.leaderboard.startRunAsync({
|
|
702
|
-
mode: 'classic' // Optional: 'classic', 'hard', etc. Defaults to 'default'
|
|
703
|
-
})
|
|
704
|
-
// Returns: { sessionId, startTime, expiresAt, hashNonce?, mode }
|
|
705
|
-
|
|
706
|
-
// Submit a score (within 1 hour of starting session)
|
|
707
|
-
const result = await VenusAPI.leaderboard.submitScoreAsync({
|
|
708
|
-
sessionId: session.sessionId,
|
|
709
|
-
score: 1500,
|
|
710
|
-
durationSec: 120,
|
|
711
|
-
mode: 'classic', // Optional: must match session mode
|
|
712
|
-
metadata: { // Optional: game-specific data (max 20KB)
|
|
713
|
-
levelCompleted: 10,
|
|
714
|
-
powerUpsUsed: 3
|
|
715
|
-
},
|
|
716
|
-
telemetry: { // Optional: anti-cheat data (max 2KB, primitives only)
|
|
717
|
-
clickCount: 245,
|
|
718
|
-
avgReactionTime: 0.32
|
|
719
|
-
},
|
|
720
|
-
hash: computedHash // Required if leaderboard uses hash verification
|
|
721
|
-
})
|
|
722
|
-
// Returns: { accepted, rank, zScore, isAnomaly }
|
|
723
|
-
|
|
724
|
-
// Get leaderboard (paginated)
|
|
725
|
-
const leaderboard = await VenusAPI.leaderboard.getLeaderboardAsync({
|
|
726
|
-
mode: 'classic', // Optional: game mode
|
|
727
|
-
period: 'daily', // Optional: 'daily', 'weekly', 'monthly', 'alltime'
|
|
728
|
-
periodDate: Date.now(), // Optional: specific period to view
|
|
729
|
-
limit: 50, // Optional: entries per page (max 50)
|
|
730
|
-
cursor: nextCursor // Optional: for pagination
|
|
731
|
-
})
|
|
732
|
-
// Returns: {
|
|
733
|
-
// variant: 'standard',
|
|
734
|
-
// entries: [{ profileId, username, avatarUrl, score, rank, ... }],
|
|
735
|
-
// totalEntries: 1234,
|
|
736
|
-
// nextCursor: 'abc123...',
|
|
737
|
-
// playerRank: 42,
|
|
738
|
-
// periodInstance: 'daily_2025-11-04'
|
|
739
|
-
// }
|
|
740
|
-
|
|
741
|
-
// Get leaderboard highlight (top players + context around you)
|
|
742
|
-
const highlight = await VenusAPI.leaderboard.getLeaderboardHighlightAsync({
|
|
743
|
-
mode: 'classic',
|
|
744
|
-
period: 'daily',
|
|
745
|
-
topCount: 3, // Top N players (podium)
|
|
746
|
-
contextAhead: 4, // Players ahead of you
|
|
747
|
-
contextBehind: 2 // Players behind you
|
|
748
|
-
})
|
|
749
|
-
// Returns: {
|
|
750
|
-
// variant: 'highlight',
|
|
751
|
-
// entries: [...],
|
|
752
|
-
// context: {
|
|
753
|
-
// topEntries: [...], // Top 3
|
|
754
|
-
// beforePlayer: [...], // 4 players ahead
|
|
755
|
-
// playerEntry: {...}, // Your entry
|
|
756
|
-
// afterPlayer: [...], // 2 players behind
|
|
757
|
-
// omittedBefore: 35, // Gap between top 3 and you
|
|
758
|
-
// omittedAfter: 100 // Players below you
|
|
759
|
-
// },
|
|
760
|
-
// playerRank: 42,
|
|
761
|
-
// totalEntries: 150
|
|
762
|
-
// }
|
|
763
|
-
|
|
764
|
-
// Get player stats
|
|
765
|
-
const stats = await VenusAPI.leaderboard.getPlayerStatsAsync({
|
|
766
|
-
mode: 'classic',
|
|
767
|
-
period: 'daily'
|
|
768
|
-
})
|
|
769
|
-
// Returns: {
|
|
770
|
-
// rank: 42,
|
|
771
|
-
// score: 1500,
|
|
772
|
-
// totalPlayers: 150,
|
|
773
|
-
// percentile: 0.72, // 72nd percentile
|
|
774
|
-
// trustScore: 85,
|
|
775
|
-
// periodInstance: 'daily_2025-11-04'
|
|
776
|
-
// }
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
#### Configuration
|
|
780
|
-
|
|
781
|
-
Add a `leaderboard` object to your game's `config.json` file:
|
|
782
|
-
|
|
783
|
-
```json
|
|
784
|
-
{
|
|
785
|
-
"leaderboard": {
|
|
786
|
-
"isDisabled": false,
|
|
787
|
-
"disabledMessage": "Leaderboards are temporarily unavailable.",
|
|
788
|
-
"requiresHash": true,
|
|
789
|
-
"hashSecret": "your-secret-key-change-in-production",
|
|
790
|
-
"scoringFields": ["score", "durationSec", "sessionId"],
|
|
791
|
-
"minDurationSec": 10,
|
|
792
|
-
"maxDurationSec": 600,
|
|
793
|
-
"minScore": 0,
|
|
794
|
-
"maxScore": 999999999,
|
|
795
|
-
"modes": {
|
|
796
|
-
"default": {
|
|
797
|
-
"displayName": "Classic Mode"
|
|
798
|
-
},
|
|
799
|
-
"hard": {
|
|
800
|
-
"displayName": "Hard Mode",
|
|
801
|
-
"minDurationSec": 5,
|
|
802
|
-
"maxDurationSec": 300
|
|
803
|
-
}
|
|
804
|
-
},
|
|
805
|
-
"periods": {
|
|
806
|
-
"daily": {
|
|
807
|
-
"displayName": "Daily",
|
|
808
|
-
"type": "daily"
|
|
809
|
-
},
|
|
810
|
-
"alltime": {
|
|
811
|
-
"displayName": "All Time",
|
|
812
|
-
"type": "alltime"
|
|
813
|
-
}
|
|
814
|
-
},
|
|
815
|
-
"antiCheat": {
|
|
816
|
-
"enableZScoreDetection": false,
|
|
817
|
-
"zScoreThreshold": 3,
|
|
818
|
-
"enableRateLimit": true,
|
|
819
|
-
"minTimeBetweenSubmissionsSec": 60,
|
|
820
|
-
"trustScoreDecayPerFlag": 10,
|
|
821
|
-
"shadowBanThreshold": 20
|
|
822
|
-
},
|
|
823
|
-
"displaySettings": {
|
|
824
|
-
"maxEntriesPerPage": 50
|
|
825
|
-
},
|
|
826
|
-
"seedEntries": {
|
|
827
|
-
"default": {
|
|
828
|
-
"daily": [
|
|
829
|
-
{
|
|
830
|
-
"score": 18500,
|
|
831
|
-
"username": "ProPlayer",
|
|
832
|
-
"avatarUrl": null,
|
|
833
|
-
"durationSec": 180
|
|
834
|
-
},
|
|
835
|
-
{
|
|
836
|
-
"score": 15200,
|
|
837
|
-
"username": "Challenger",
|
|
838
|
-
"avatarUrl": null,
|
|
839
|
-
"durationSec": 210
|
|
840
|
-
}
|
|
841
|
-
]
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
```
|
|
847
|
-
|
|
848
|
-
**Configuration Options:**
|
|
849
|
-
|
|
850
|
-
- `isDisabled`: Globally disable leaderboards
|
|
851
|
-
- `requiresHash`: Enable HMAC-based score verification (recommended for production)
|
|
852
|
-
- `hashSecret`: Secret key for HMAC verification (keep this secure!)
|
|
853
|
-
- `scoringFields`: Fields included in hash verification (can include nested fields like `metadata.level`)
|
|
854
|
-
- `minDurationSec` / `maxDurationSec`: Valid gameplay duration range
|
|
855
|
-
- `minScore` / `maxScore`: Valid score bounds
|
|
856
|
-
- `modes`: Game modes (can override min/max values per mode)
|
|
857
|
-
- `periods`: Time periods for leaderboards (`daily`, `weekly`, `monthly`, `alltime`)
|
|
858
|
-
- `antiCheat`: Anti-cheat settings
|
|
859
|
-
- `seedEntries`: Pre-populate leaderboards with NPC scores (nested by mode → period)
|
|
860
|
-
|
|
861
|
-
**Features:**
|
|
862
|
-
- **Multiple Modes**: Support different game modes (classic, hard, etc.)
|
|
863
|
-
- **Time Periods**: Daily, weekly, monthly, and all-time leaderboards
|
|
864
|
-
- **Anti-Cheat**: Session validation, rate limiting, hash verification, z-score anomaly detection
|
|
865
|
-
- **Shadow Banning**: Cheaters see their own scores but are hidden from others
|
|
866
|
-
- **Trust Scores**: Per-player reputation that decays with suspicious behavior
|
|
867
|
-
- **Seed Entries**: Pre-populate leaderboards with NPC scores
|
|
868
|
-
- **Pagination**: Cursor-based pagination for large leaderboards
|
|
869
|
-
- **UTC-Based Periods**: All players globally compete in same daily/weekly/monthly periods
|
|
870
|
-
|
|
871
|
-
**Security Notes:**
|
|
872
|
-
- Session tokens expire after 1 hour and can only be used once to prevent replay attacks
|
|
873
|
-
- Use `requiresHash: true` in production with a strong `hashSecret`
|
|
874
|
-
- Keep `hashSecret` out of version control (use environment variables or local config)
|
|
875
|
-
- Store `hashSecret` in `config.local.json` (gitignored) for local development
|
|
876
|
-
|
|
877
|
-
---
|
|
878
|
-
|
|
879
|
-
## Mock Mode
|
|
880
|
-
|
|
881
|
-
All APIs have complete mock implementations for local development:
|
|
882
|
-
|
|
883
|
-
```typescript
|
|
884
|
-
import { default as VenusAPI } from '@series-inc/venus-sdk/api'
|
|
885
|
-
|
|
886
|
-
await VenusAPI.initializeAsync({ mock: true })
|
|
887
|
-
|
|
888
|
-
// All APIs work the same, but with simulated responses
|
|
889
|
-
const state = await VenusAPI.simulation.getStateAsync()
|
|
890
|
-
```
|
|
891
|
-
|
|
892
|
-
### Custom Mock Data
|
|
893
|
-
|
|
894
|
-
```typescript
|
|
895
|
-
await VenusAPI.initializeAsync({
|
|
896
|
-
mock: {
|
|
897
|
-
simulation: {
|
|
898
|
-
state: { customData: 'value' }
|
|
899
|
-
},
|
|
900
|
-
profile: {
|
|
901
|
-
name: 'Test User',
|
|
902
|
-
username: 'test_user'
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
})
|
|
906
|
-
```
|
|
907
|
-
|
|
908
|
-
---
|
|
909
|
-
|
|
910
|
-
## RPC Transport
|
|
911
|
-
|
|
912
|
-
The SDK uses an RPC (Remote Procedure Call) architecture for communication:
|
|
913
|
-
|
|
914
|
-
```typescript
|
|
915
|
-
import { RpcClient, VenusTransport } from 'venus-sdk'
|
|
916
|
-
|
|
917
|
-
// Low-level RPC client
|
|
918
|
-
const transport = new VenusTransport()
|
|
919
|
-
const rpcClient = new RpcClient(transport)
|
|
920
|
-
|
|
921
|
-
// Send request
|
|
922
|
-
const response = await rpcClient.request({
|
|
923
|
-
method: 'simulation.getState',
|
|
924
|
-
params: { roomId: 'room_123' }
|
|
925
|
-
})
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
---
|
|
929
|
-
|
|
930
|
-
## Build Configuration
|
|
931
|
-
|
|
932
|
-
The package is built with `tsup` and provides multiple module formats:
|
|
933
|
-
|
|
934
|
-
```json
|
|
935
|
-
{
|
|
936
|
-
"main": "./dist/index.cjs",
|
|
937
|
-
"module": "./dist/index.mjs",
|
|
938
|
-
"types": "./dist/index.d.ts",
|
|
939
|
-
"exports": {
|
|
940
|
-
".": {
|
|
941
|
-
"types": "./dist/index.d.ts",
|
|
942
|
-
"import": "./dist/index.mjs",
|
|
943
|
-
"require": "./dist/index.cjs"
|
|
944
|
-
},
|
|
945
|
-
"./api": {
|
|
946
|
-
"types": "./dist/venus-api/index.d.ts",
|
|
947
|
-
"import": "./dist/venus-api/index.mjs",
|
|
948
|
-
"require": "./dist/venus-api/index.cjs"
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
```
|
|
953
|
-
|
|
954
|
-
---
|
|
955
|
-
|
|
956
|
-
## TypeScript Configuration
|
|
957
|
-
|
|
958
|
-
The package uses TypeScript 5.9+ with strict type checking:
|
|
959
|
-
|
|
960
|
-
```json
|
|
961
|
-
{
|
|
962
|
-
"compilerOptions": {
|
|
963
|
-
"strict": true,
|
|
964
|
-
"target": "ES2020",
|
|
965
|
-
"module": "ESNext",
|
|
966
|
-
"moduleResolution": "bundler"
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
```
|
|
970
|
-
|
|
971
|
-
---
|
|
972
|
-
|
|
973
|
-
## Testing
|
|
974
|
-
|
|
975
|
-
```bash
|
|
976
|
-
# Run unit tests
|
|
977
|
-
npm test
|
|
978
|
-
|
|
979
|
-
# Run tests in watch mode
|
|
980
|
-
npm test -- --watch
|
|
981
|
-
```
|
|
982
|
-
|
|
983
|
-
Tests are written using Jest with JSDOM environment for browser API simulation.
|
|
984
|
-
|
|
985
|
-
---
|
|
986
|
-
|
|
987
|
-
## License
|
|
988
|
-
|
|
989
|
-
MIT
|
|
990
|
-
|
|
991
|
-
---
|
|
27
|
+
## Documentation
|
|
992
28
|
|
|
993
|
-
|
|
29
|
+
The complete Venus SDK manuals live on [Venus Docs](https://series-1.gitbook.io/getreel-docs). Start there for setup guides, API references, tutorials, and best practices.
|
|
994
30
|
|
|
995
|
-
|
|
996
|
-
- [npm Package](https://www.npmjs.com/package/venus-sdk)
|
|
997
|
-
- [Issue Tracker](https://github.com/SeriesAI/venus-sdk/issues)
|
|
31
|
+
## Support & Links
|
|
998
32
|
|
|
33
|
+
- [Join our Discord!](https://discord.gg/NcjhKQHx)
|