@thestatic-tv/dcl-sdk 2.3.0-dev.0 → 2.4.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
@@ -5,475 +5,117 @@ Connect your Decentraland scene to [thestatic.tv](https://thestatic.tv) - the de
5
5
  [![npm version](https://img.shields.io/npm/v/@thestatic-tv/dcl-sdk?color=00e5e5)](https://www.npmjs.com/package/@thestatic-tv/dcl-sdk)
6
6
  [![DCL SDK](https://img.shields.io/badge/DCL%20SDK-7.x-blue)](https://docs.decentraland.org/)
7
7
 
8
- This SDK allows DCL scene builders to:
9
- - Track visitors to your Decentraland scene
10
- - Display the full thestatic.tv channel lineup in their scenes
11
- - Track video watching metrics
12
- - Enable likes/follows from within DCL
13
- - Get referral credit for driving traffic to channels
8
+ ## Features
14
9
 
15
- ## Pricing
10
+ - **Visitor Analytics** - Track visitors and session metrics
11
+ - **Channel Guide** - Display live streams and VODs in your scene
12
+ - **Watch Metrics** - Track video viewing time
13
+ - **Interactions** - Enable likes/follows from within DCL
14
+ - **Built-in UI** - Pre-built Guide and Chat components
15
+ - **Admin Panel** - In-scene controls for Pro tier
16
16
 
17
- | Tier | Price | Features |
18
- |------|-------|----------|
19
- | **Lite** | $5/mo | Session/visitor tracking, Guide button, Chat button |
20
- | **Full** | $10/mo | Lite + Guide UI, Chat UI, Heartbeat, Interactions |
21
- | **Pro** | $15/mo | Full + Admin Panel (Video tab, Mod tab) |
22
- | **Custom** | $20/mo | Pro + Custom scene tabs for scene-specific controls |
23
-
24
- > **All keys use `dcls_` prefix** - the server determines your subscription level.
25
- >
26
- > **Free Trial**: All new scene keys include a 7-day free trial!
27
- >
28
- > **Expiry Warnings**: You'll receive dashboard notifications at 7, 3, and 1 days before your subscription expires.
29
-
30
- Get your key from [thestatic.tv/dashboard](https://thestatic.tv/dashboard) → DCL Scenes tab.
31
-
32
- ### Coordinate Locking
33
-
34
- When you create a scene key, you'll be asked to confirm your parcel coordinates. **Once confirmed, coordinates are permanently locked** to prevent key reuse across different scenes. This ensures analytics accurately reflect a single scene.
35
-
36
- ### Key Rotation
37
-
38
- If you need to rotate your API key (e.g., if compromised), you can do so from the dashboard without losing your subscription or analytics history. The old key is immediately invalidated.
39
-
40
- ## Example Scene
41
-
42
- Clone our example scene to get started quickly:
43
-
44
- ```bash
45
- git clone https://github.com/thestatic-tv/thestatic-dcl-example.git
46
- cd thestatic-dcl-example
47
- npm install
48
- npm start
49
- ```
17
+ ## Quick Start
50
18
 
51
- See the [example repo](https://github.com/thestatic-tv/thestatic-dcl-example) for a complete working scene with video player integration.
19
+ 1. Get your API key from [thestatic.tv/dashboard](https://thestatic.tv/dashboard) (DCL Scenes tab)
52
20
 
53
- ## Installation
21
+ 2. Install the SDK:
54
22
 
55
23
  ```bash
56
24
  npm install @thestatic-tv/dcl-sdk
57
25
  ```
58
26
 
59
- ## Quick Start
60
-
61
- 1. Get your API key from [thestatic.tv/dashboard](https://thestatic.tv/dashboard) (DCL Scenes tab)
62
-
63
- 2. Initialize the client in your scene's `main()` function:
27
+ 3. Initialize in your scene:
64
28
 
65
29
  ```typescript
66
- import {} from '@dcl/sdk/math'
67
- import { engine } from '@dcl/sdk/ecs'
68
30
  import { StaticTVClient } from '@thestatic-tv/dcl-sdk'
69
31
 
70
32
  let staticTV: StaticTVClient
71
33
 
72
34
  export function main() {
73
35
  staticTV = new StaticTVClient({
74
- apiKey: 'dcls_your_api_key_here'
36
+ apiKey: 'your_api_key_here'
75
37
  })
76
- // Session tracking starts automatically!
38
+ // Session tracking starts automatically
77
39
  }
78
40
  ```
79
41
 
80
- 3. Fetch channels and display them (Full mode only):
81
-
82
- ```typescript
83
- // Get all channels
84
- const channels = await staticTV.guide.getChannels()
42
+ ## Example Scene
85
43
 
86
- // Get only live channels
87
- const liveChannels = await staticTV.guide.getLiveChannels()
44
+ Clone our starter scene to get up and running quickly:
88
45
 
89
- // Get a specific channel
90
- const channel = await staticTV.guide.getChannel('channel-slug')
46
+ ```bash
47
+ git clone https://github.com/thestatic-tv/thestatic-dcl-starter.git
48
+ cd thestatic-dcl-starter
49
+ npm install
50
+ npm start
91
51
  ```
92
52
 
93
- 4. Track video watching:
53
+ ## Basic Usage
94
54
 
95
55
  ```typescript
96
- // When user enters video viewing area
97
- staticTV.heartbeat.startWatching('channel-slug')
56
+ // Get channels (Standard/Pro tier)
57
+ const channels = await staticTV.guide.getChannels()
58
+ const liveChannels = await staticTV.guide.getLiveChannels()
98
59
 
99
- // When user leaves video viewing area
60
+ // Track video watching
61
+ staticTV.heartbeat.startWatching('channel-slug')
100
62
  staticTV.heartbeat.stopWatching()
101
- ```
102
-
103
- 5. Enable interactions:
104
63
 
105
- ```typescript
106
- // Like a channel (requires wallet connection)
64
+ // User interactions (requires wallet)
107
65
  await staticTV.interactions.like('channel-slug')
108
-
109
- // Follow a channel
110
66
  await staticTV.interactions.follow('channel-slug')
111
- ```
112
67
 
113
- 6. Cleanup before scene unload:
68
+ // Check your tier
69
+ console.log('Tier:', staticTV.tier) // 'free', 'standard', or 'pro'
114
70
 
115
- ```typescript
71
+ // Cleanup
116
72
  await staticTV.destroy()
117
73
  ```
118
74
 
119
- ## Lite Mode (Visitor Tracking Only)
120
-
121
- If you don't have a channel but want to track visitors to your scene:
122
-
123
- 1. Get a scene key from [thestatic.tv/dashboard](https://thestatic.tv/dashboard) (DCL Scenes tab)
124
-
125
- 2. Initialize with your scene key in `main()`:
126
-
127
- ```typescript
128
- import {} from '@dcl/sdk/math'
129
- import { engine } from '@dcl/sdk/ecs'
130
- import { StaticTVClient } from '@thestatic-tv/dcl-sdk'
131
-
132
- let staticTV: StaticTVClient
133
-
134
- export function main() {
135
- staticTV = new StaticTVClient({
136
- apiKey: 'dcls_your_scene_key_here'
137
- })
138
- // Session tracking starts automatically!
139
- }
140
- ```
141
-
142
- 3. Check if running in lite mode:
143
-
144
- ```typescript
145
- if (staticTV.isLite) {
146
- console.log('Running in lite mode - session tracking only')
147
- }
148
-
149
- // guide, heartbeat, and interactions are null in lite mode
150
- if (staticTV.guide) {
151
- const channels = await staticTV.guide.getChannels()
152
- }
153
- ```
154
-
155
- ## API Reference
156
-
157
- ### StaticTVClient
158
-
159
- Main client class for interacting with thestatic.tv.
160
-
161
- #### Constructor Options
162
-
163
- | Option | Type | Default | Description |
164
- |--------|------|---------|-------------|
165
- | `apiKey` | `string` | required | Your API key (all keys use `dcls_` prefix) |
166
- | `autoStartSession` | `boolean` | `true` | Automatically start session tracking |
167
- | `sessionHeartbeatInterval` | `number` | `30000` | Session heartbeat interval (ms) |
168
- | `watchHeartbeatInterval` | `number` | `60000` | Watch heartbeat interval (ms) |
169
- | `debug` | `boolean` | `false` | Enable debug logging |
170
-
171
- #### Properties
172
-
173
- | Property | Type | Description |
174
- |----------|------|-------------|
175
- | `keyType` | `'channel' \| 'scene'` | The detected key type |
176
- | `isLite` | `boolean` | `true` if using a scene key (lite mode) |
177
- | `hasProFeatures` | `boolean` | `true` if pro features are enabled |
178
- | `guide` | `GuideModule \| null` | Guide module (null in lite mode) |
179
- | `session` | `SessionModule` | Session module (always available) |
180
- | `heartbeat` | `HeartbeatModule \| null` | Heartbeat module (null in lite mode) |
181
- | `interactions` | `InteractionsModule \| null` | Interactions module (null in lite mode) |
182
- | `guideUI` | `GuideUIModule \| null` | Guide UI module (null in lite mode) |
183
- | `chatUI` | `ChatUIModule \| null` | Chat UI module (null in lite mode) |
184
- | `adminPanel` | `AdminPanelUIModule \| null` | Admin panel (null until enableProFeatures() called) |
185
-
186
- #### Methods
187
-
188
- | Method | Description |
189
- |--------|-------------|
190
- | `enableProFeatures(config)` | Enable Pro tier admin panel |
191
- | `registerSceneTab(tab)` | Add custom scene tab (Custom tier) |
192
- | `destroy()` | Cleanup before scene unload |
193
-
194
- ### Guide Module (Full Mode Only)
195
-
196
- ```typescript
197
- staticTV.guide.getChannels() // Get all channels (cached 30s)
198
- staticTV.guide.getLiveChannels() // Get only live channels
199
- staticTV.guide.getChannel(slug) // Get a specific channel
200
- staticTV.guide.getVods() // Get VODs
201
- staticTV.guide.clearCache() // Clear the channel cache
202
- ```
203
-
204
- ### Session Module
205
-
206
- Session tracking starts automatically by default.
207
-
208
- ```typescript
209
- staticTV.session.startSession() // Manually start session
210
- staticTV.session.endSession() // End session
211
- staticTV.session.getSessionId() // Get current session ID
212
- staticTV.session.isSessionActive() // Check if session is active
213
- ```
214
-
215
- ### Heartbeat Module (Full Mode Only)
216
-
217
- Track video watching. Each heartbeat represents 1 minute watched.
218
-
219
- ```typescript
220
- staticTV.heartbeat.startWatching(channelSlug) // Start tracking
221
- staticTV.heartbeat.stopWatching() // Stop tracking
222
- staticTV.heartbeat.getCurrentChannel() // Get currently watched channel
223
- staticTV.heartbeat.isCurrentlyWatching() // Check if watching
224
- ```
225
-
226
- ### Interactions Module (Full Mode Only)
75
+ ## Built-in UI Components
227
76
 
228
- Like and follow channels. Requires wallet connection.
77
+ The SDK includes pre-built UI for channel browsing and chat:
229
78
 
230
79
  ```typescript
231
- staticTV.interactions.like(channelSlug) // Like a channel
232
- staticTV.interactions.follow(channelSlug) // Follow a channel
233
- ```
234
-
235
- ### Guide UI Module (Full Mode Only)
236
-
237
- Built-in channel browser UI. You provide a callback to handle video selection.
238
-
239
- ```typescript
240
- let staticTV: StaticTVClient
241
-
242
- export function main() {
243
- staticTV = new StaticTVClient({
244
- apiKey: 'dcls_your_api_key',
245
- guideUI: {
246
- onVideoSelect: (video) => {
247
- // Handle video playback in your scene
248
- console.log('Playing:', video.name, video.src)
249
- }
80
+ staticTV = new StaticTVClient({
81
+ apiKey: 'your_api_key',
82
+ guideUI: {
83
+ onVideoSelect: (video) => {
84
+ // Handle video playback
85
+ console.log('Playing:', video.name)
250
86
  }
251
- })
87
+ },
88
+ chatUI: {
89
+ position: 'right'
90
+ }
91
+ })
252
92
 
253
- // Initialize the UI (call once after client is created)
254
- staticTV.guideUI.init()
255
- }
93
+ // Initialize UI components
94
+ staticTV.guideUI.init()
95
+ staticTV.chatUI.init()
256
96
 
257
- // Show/hide the guide
258
- staticTV.guideUI.show()
259
- staticTV.guideUI.hide()
97
+ // Show/hide
260
98
  staticTV.guideUI.toggle()
261
-
262
- // Check visibility
263
- if (staticTV.guideUI.isVisible) { ... }
264
-
265
- // Update "PLAYING" indicator
266
- staticTV.guideUI.currentVideoId = 'video-id'
267
-
268
- // Refresh data
269
- await staticTV.guideUI.refresh()
270
- ```
271
-
272
- ### Chat UI Module (Full Mode Only)
273
-
274
- Real-time chat with Firebase authentication.
275
-
276
- ```typescript
277
- let staticTV: StaticTVClient
278
-
279
- export function main() {
280
- staticTV = new StaticTVClient({
281
- apiKey: 'dcls_your_api_key',
282
- chatUI: {
283
- position: 'right', // 'left', 'center', or 'right'
284
- fontScale: 1.0
285
- }
286
- })
287
-
288
- // Initialize the chat (call once after client is created)
289
- staticTV.chatUI.init()
290
- }
291
-
292
- // Show/hide the chat
293
- staticTV.chatUI.show()
294
- staticTV.chatUI.hide()
295
99
  staticTV.chatUI.toggle()
296
-
297
- // Check visibility
298
- if (staticTV.chatUI.isVisible) { ... }
299
-
300
- // Get unread message count (for badge display)
301
- const unread = staticTV.chatUI.unreadCount
302
-
303
- // Switch channels
304
- staticTV.chatUI.setChannel('channel-slug')
305
100
  ```
306
101
 
307
- ### Admin Panel Module (Pro Tier)
102
+ ## Pricing & Tiers
308
103
 
309
- In-scene admin panel with Video and Mod tabs. Allows scene owners/admins to:
310
- - Control live streaming (start/stop, rotate keys)
311
- - Play videos from URL or predefined slots
312
- - Manage scene admins and banned wallets
313
- - Send broadcast messages to all players
104
+ See [thestatic.tv/info](https://thestatic.tv/info) for current pricing and tier features.
314
105
 
315
- ```typescript
316
- import { StaticTVClient } from '@thestatic-tv/dcl-sdk'
317
- import ReactEcs, { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
106
+ All new keys include a **7-day free trial**.
318
107
 
319
- let staticTV: StaticTVClient
108
+ ## Documentation
320
109
 
321
- export function main() {
322
- staticTV = new StaticTVClient({
323
- apiKey: 'dcls_your_api_key'
324
- })
110
+ Full API reference and Pro tier features (Admin Panel, Custom Tabs) available at:
325
111
 
326
- // Enable admin panel (Pro tier)
327
- staticTV.enableProFeatures({
328
- sceneId: 'my-scene', // Your scene ID from thestatic.tv
329
- title: 'MY SCENE ADMIN', // Panel header title
330
- onVideoPlay: (url) => {
331
- // Handle video playback in your scene
332
- videoPlayer.play(url)
333
- },
334
- onVideoStop: () => {
335
- videoPlayer.stop()
336
- },
337
- onVideoSlotPlay: (slot) => {
338
- // Play a predefined video slot (slot1-slot5)
339
- fetchAndPlaySlot(slot)
340
- },
341
- onBroadcast: (text) => {
342
- // Show notification to all players
343
- showNotification(text)
344
- },
345
- onCommand: (type, payload) => {
346
- // Handle custom commands (kickAll, kickBanned, etc.)
347
- handleCommand(type, payload)
348
- }
349
- })
350
- }
351
-
352
- // Render the admin panel
353
- ReactEcsRenderer.setUiRenderer(() => {
354
- return staticTV.adminPanel?.getComponent()
355
- })
356
-
357
- // Toggle panel visibility
358
- staticTV.adminPanel.toggle()
359
-
360
- // Check if user has admin access
361
- if (staticTV.adminPanel.hasAccess) { ... }
362
- ```
363
-
364
- #### Admin Panel Configuration Options
365
-
366
- | Option | Type | Default | Description |
367
- |--------|------|---------|-------------|
368
- | `sceneId` | `string` | required | Scene ID for API calls |
369
- | `title` | `string` | `'ADMIN PANEL'` | Header title |
370
- | `headerColor` | `{r,g,b,a}` | red | Header background color |
371
- | `showVideoTab` | `boolean` | `true` | Show Video tab |
372
- | `showModTab` | `boolean` | `true` | Show Mod tab (owners only) |
373
- | `onVideoPlay` | `(url) => void` | - | Called when video should play |
374
- | `onVideoStop` | `() => void` | - | Called when video should stop |
375
- | `onVideoSlotPlay` | `(slot) => void` | - | Called when slot is selected |
376
- | `onBroadcast` | `(text) => void` | - | Called for broadcast messages |
377
- | `onCommand` | `(type, payload) => void` | - | Called for custom commands |
378
- | `footerLink` | `string` | scene page | Link shown in footer |
379
- | `debug` | `boolean` | `false` | Enable debug logging |
380
-
381
- ### Custom Scene Tabs (Custom Tier)
382
-
383
- Add your own scene-specific control tabs to the admin panel:
384
-
385
- ```typescript
386
- import ReactEcs, { UiEntity, Button, Label } from '@dcl/sdk/react-ecs'
387
-
388
- // Enable pro features first
389
- staticTV.enableProFeatures({ sceneId: 'my-scene', ... })
390
-
391
- // Register custom tabs
392
- staticTV.registerSceneTab({
393
- label: 'LIGHTS',
394
- id: 'lights',
395
- render: () => (
396
- <UiEntity uiTransform={{ flexDirection: 'column', padding: 8 }}>
397
- <Label value="Light Controls" fontSize={14} />
398
- <Button value="Disco Mode" onMouseDown={() => setDiscoLights()} />
399
- <Button value="Ambient" onMouseDown={() => setAmbientLights()} />
400
- <Button value="Off" onMouseDown={() => turnOffLights()} />
401
- </UiEntity>
402
- )
403
- })
404
-
405
- staticTV.registerSceneTab({
406
- label: 'DOORS',
407
- id: 'doors',
408
- render: () => <MyDoorsControls />
409
- })
410
- ```
411
-
412
- Custom tabs appear before the Video and Mod tabs in the tab bar.
413
-
414
- ### Rendering UI Components
415
-
416
- The UI modules provide `getComponent()` methods that return React-ECS elements. Add the renderer **outside** your `main()` function:
417
-
418
- ```typescript
419
- import ReactEcs, { ReactEcsRenderer, UiEntity } from '@dcl/sdk/react-ecs'
420
-
421
- // Outside main() - required by DCL
422
- ReactEcsRenderer.setUiRenderer(() => {
423
- if (!staticTV) return null
424
- return ReactEcs.createElement(UiEntity, {
425
- uiTransform: { width: '100%', height: '100%', positionType: 'absolute' },
426
- children: [
427
- staticTV.guideUI?.getComponent(),
428
- staticTV.chatUI?.getComponent()
429
- ].filter(Boolean)
430
- })
431
- })
432
- ```
433
-
434
- ## Metrics Attribution
435
-
436
- This SDK implements dual attribution:
437
-
438
- - **Watched Channel**: Gets view metrics (minutes watched, likes, follows)
439
- - **Scene Owner**: Gets referral metrics (unique visitors, traffic driven)
440
-
441
- Your channel (linked to your API key) receives credit for all traffic your scene drives to thestatic.tv channels.
442
-
443
- ## Types
444
-
445
- ```typescript
446
- interface Channel {
447
- id: string
448
- slug: string
449
- name: string
450
- streamUrl: string
451
- isLive: boolean
452
- currentViewers: number
453
- poster: string | null
454
- logo: string | null
455
- description: string
456
- }
457
-
458
- interface Vod {
459
- id: string
460
- title: string
461
- url: string
462
- thumbnail: string | null
463
- channelId: string
464
- }
465
- ```
466
-
467
- ## Requirements
468
-
469
- - Decentraland SDK 7.0.0 or higher
470
- - API key from thestatic.tv
112
+ - **Docs**: [thestatic.tv/info](https://thestatic.tv/info)
113
+ - **Examples**: [github.com/thestatic-tv/thestatic-dcl-starter](https://github.com/thestatic-tv/thestatic-dcl-starter)
471
114
 
472
115
  ## Support
473
116
 
474
- - Documentation: [thestatic.tv/info](https://thestatic.tv/info)
475
- - Issues: [GitHub Issues](https://github.com/thestatic-tv/dcl-sdk/issues)
476
117
  - Discord: [thestatic.tv Discord](https://discord.gg/thestatic)
118
+ - Issues: [GitHub Issues](https://github.com/thestatic-tv/dcl-sdk/issues)
477
119
 
478
120
  ## License
479
121