SDK Reference

Full documentation for the @kidsbuild/sdk package.

Installation

Install the SDK using your preferred package manager:

Terminal
$npm install @kidsbuild/sdk

Or with yarn/pnpm:

Terminal
$yarn add @kidsbuild/sdk
$# or
$pnpm add @kidsbuild/sdk

Quick Setup

Wrap your app in the KidsBuild provider to access all SDK features:

src/App.tsxtsx
import { KidsBuild } from '@kidsbuild/sdk'

export default function App() {
  return (
    <KidsBuild appId="your-app-id">
      <YourAppContent />
    </KidsBuild>
  )
}

Core Hooks

useUser()

Returns the current user's information or null if not logged in.

import { useUser } from '@kidsbuild/sdk'

function Profile() {
  const user = useUser()
  
  if (!user) return <div>Please log in</div>
  
  return (
    <div>
      <img src={user.avatarUrl} alt={user.displayName} />
      <h2>{user.displayName}</h2>
      <p>@{user.username}</p>
      <p>Member since {user.createdAt}</p>
    </div>
  )
}

// User type
interface User {
  id: string
  username: string
  displayName: string
  avatarUrl: string | null
  createdAt: string
  isVerified: boolean
}

useWallet()

Returns the user's wallet balances for BuildBucks and TutorBucks.

import { useWallet } from '@kidsbuild/sdk'

function WalletDisplay() {
  const wallet = useWallet()
  
  if (!wallet) return null
  
  return (
    <div>
      <p>BuildBucks: {wallet.buildBucks}</p>
      <p>TutorBucks: {wallet.tutorBucks}</p>
    </div>
  )
}

// Wallet type
interface Wallet {
  buildBucks: number
  tutorBucks: number
  pendingBuildBucks: number  // Earned but not yet confirmed
  pendingTutorBucks: number
}

useAppState()

Persistent state that automatically saves and loads for each user. This is the primary way to store data in your app.

import { useAppState } from '@kidsbuild/sdk'

// Simple value
function Counter() {
  const [count, setCount] = useAppState('counter', 0)
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  )
}

// Object state
function Settings() {
  const [settings, setSettings] = useAppState('settings', {
    sound: true,
    difficulty: 'normal',
    theme: 'dark'
  })
  
  const toggleSound = () => {
    setSettings({ ...settings, sound: !settings.sound })
  }
  
  return (
    <button onClick={toggleSound}>
      Sound: {settings.sound ? 'On' : 'Off'}
    </button>
  )
}

// Array state
function TodoList() {
  const [todos, setTodos] = useAppState<string[]>('todos', [])
  
  const addTodo = (text: string) => {
    setTodos([...todos, text])
  }
  
  const removeTodo = (index: number) => {
    setTodos(todos.filter((_, i) => i !== index))
  }
  
  return (
    <ul>
      {todos.map((todo, i) => (
        <li key={i}>
          {todo}
          <button onClick={() => removeTodo(i)}>Remove</button>
        </li>
      ))}
    </ul>
  )
}

useLeaderboard()

Fetches and manages leaderboard data for your app.

import { useLeaderboard } from '@kidsbuild/sdk'

function Leaderboard() {
  const { entries, isLoading, submitScore, userRank } = useLeaderboard('high-scores')
  
  if (isLoading) return <div>Loading...</div>
  
  return (
    <div>
      <p>Your rank: #{userRank}</p>
      <ol>
        {entries.map((entry, i) => (
          <li key={entry.userId}>
            {entry.displayName}: {entry.score}
          </li>
        ))}
      </ol>
      <button onClick={() => submitScore(1000)}>
        Submit Score
      </button>
    </div>
  )
}

// Leaderboard types
interface LeaderboardEntry {
  userId: string
  displayName: string
  avatarUrl: string | null
  score: number
  achievedAt: string
}

interface UseLeaderboardReturn {
  entries: LeaderboardEntry[]
  isLoading: boolean
  error: Error | null
  submitScore: (score: number) => Promise<void>
  userRank: number | null
  refresh: () => void
}

Payments

usePayment()

Handle BuildBucks payments within your app (for paid features, tips, etc.).

import { usePayment } from '@kidsbuild/sdk'

function PremiumFeature() {
  const { requestPayment, isProcessing } = usePayment()
  
  const unlockFeature = async () => {
    try {
      const result = await requestPayment({
        amount: 50,  // BuildBucks
        description: 'Unlock premium level pack',
        metadata: { featureId: 'premium-levels' }
      })
      
      if (result.success) {
        // Payment successful, unlock the feature
        console.log('Transaction ID:', result.transactionId)
      }
    } catch (error) {
      // User cancelled or insufficient funds
      console.error('Payment failed:', error)
    }
  }
  
  return (
    <button onClick={unlockFeature} disabled={isProcessing}>
      {isProcessing ? 'Processing...' : 'Unlock for 50 BB'}
    </button>
  )
}

Analytics

useAnalytics()

Track events and user behavior in your app.

import { useAnalytics } from '@kidsbuild/sdk'

function Game() {
  const { track } = useAnalytics()
  
  const startGame = () => {
    track('game_started', { difficulty: 'hard' })
  }
  
  const endGame = (score: number) => {
    track('game_ended', { 
      score, 
      playTime: 120,
      levelsCompleted: 5 
    })
  }
  
  return <button onClick={startGame}>Start Game</button>
}

// Built-in events
// track('app_opened')          - Auto-tracked
// track('session_started')     - Auto-tracked
// track('button_clicked', { buttonId: string })
// track('screen_viewed', { screenName: string })
// track('error_occurred', { message: string })

TypeScript Support

The SDK is fully typed. You can extend types for your specific state shapes:

import { useAppState } from '@kidsbuild/sdk'

// Define your state types
interface GameState {
  level: number
  score: number
  achievements: string[]
  settings: {
    sound: boolean
    music: boolean
  }
}

// Use with generics
function Game() {
  const [state, setState] = useAppState<GameState>('game', {
    level: 1,
    score: 0,
    achievements: [],
    settings: { sound: true, music: true }
  })
  
  // TypeScript knows the shape of state
  const nextLevel = () => {
    setState({
      ...state,
      level: state.level + 1
    })
  }
}

Error Handling

The SDK provides consistent error handling across all operations:

import { useAppState, KidsBuildError } from '@kidsbuild/sdk'

function SaveGame() {
  const [state, setState, { isLoading, error }] = useAppState('game', {})
  
  if (error) {
    if (error instanceof KidsBuildError) {
      switch (error.code) {
        case 'NETWORK_ERROR':
          return <div>Check your internet connection</div>
        case 'AUTH_REQUIRED':
          return <div>Please log in to save</div>
        case 'QUOTA_EXCEEDED':
          return <div>Storage limit reached</div>
        default:
          return <div>Something went wrong: {error.message}</div>
      }
    }
  }
  
  return <div>Game loaded!</div>
}

Next Steps