@ludus/developer-portal
The developer portal SDK. Provides React hooks, dashboard components, and Firestore converters for the Ludus game developer experience — submission management, analytics, revenue tracking, payout requests, and version history.
Installation
Section titled “Installation”npm install @ludus/developer-portalArchitecture
Section titled “Architecture”The portal uses a provider pattern: all hooks accept a provider interface as their first argument, keeping the portal transport-agnostic. Swap providers to switch between Firestore, REST APIs, or test mocks without changing component code.
Providers
Section titled “Providers”Five provider interfaces define the data layer:
import type { SubmissionProvider, RevenueProvider, AnalyticsProvider, VersionProvider, ProfileProvider,} from '@ludus/developer-portal';SubmissionProvider
Section titled “SubmissionProvider”interface SubmissionProvider { listByDeveloper(developerId: string): Promise<PortalSubmission[]>; getSubmission(submissionId: string): Promise<PortalSubmission>; submitForReview(submissionId: string): Promise<void>;}RevenueProvider
Section titled “RevenueProvider”interface RevenueProvider { getSummary(developerId: string): Promise<RevenueSummary>; getPayouts(developerId: string): Promise<PortalPayout[]>; requestPayout(developerId: string): Promise<PortalPayout>; getRevenueTimeSeries(developerId: string, period: TimePeriod): Promise<TimeSeriesPoint[]>;}AnalyticsProvider
Section titled “AnalyticsProvider”interface AnalyticsProvider { getGameAnalytics(gameId: string, period: TimePeriod): Promise<GameAnalytics>; getDeveloperOverview(developerId: string): Promise<DeveloperOverview>;}VersionProvider
Section titled “VersionProvider”interface VersionProvider { getVersions(gameName: string): Promise<PortalVersionEntry[]>; getLatest(gameName: string): Promise<PortalVersionEntry | null>;}ProfileProvider
Section titled “ProfileProvider”interface ProfileProvider { getProfile(developerId: string): Promise<DeveloperProfile>; updateProfile( developerId: string, update: Partial<Omit<DeveloperProfile, 'id' | 'joinedAt' | 'verified'>>, ): Promise<DeveloperProfile>;}Six React hooks for data fetching and mutations:
useSubmissions
Section titled “useSubmissions”import { useSubmissions } from '@ludus/developer-portal';import type { UseSubmissionsResult } from '@ludus/developer-portal';
function MySubmissions({ provider, developerId }) { const { submissions, loading, error, refresh } = useSubmissions(provider, developerId);
return submissions.map(s => ( <div key={s.id}>{s.gameName} v{s.version} — {s.status}</div> ));}useGameAnalytics
Section titled “useGameAnalytics”import { useGameAnalytics } from '@ludus/developer-portal';import type { UseGameAnalyticsResult } from '@ludus/developer-portal';
const { analytics, loading, error } = useGameAnalytics(provider, gameId, 'week');// analytics: { gamesPlayed, uniquePlayers, avgGameDurationMs, completionRate,// abandonmentRate, avgRating, ratingCount, retention, revenue }useRevenue
Section titled “useRevenue”import { useRevenue } from '@ludus/developer-portal';import type { UseRevenueResult } from '@ludus/developer-portal';
const { summary, timeSeries, loading, error } = useRevenue(provider, developerId, 'month');// summary: { totalFees, developerShare, protocolShare, pendingPayout, currency }// timeSeries: [{ date, value }, ...]usePayouts
Section titled “usePayouts”import { usePayouts } from '@ludus/developer-portal';import type { UsePayoutsResult } from '@ludus/developer-portal';
const { payouts, pendingAmount, requestPayout, requesting, loading, error } = usePayouts(provider, developerId);
// Request a new payoutawait requestPayout();useVersions
Section titled “useVersions”import { useVersions } from '@ludus/developer-portal';import type { UseVersionsResult } from '@ludus/developer-portal';
const { versions, latest, loading, error } = useVersions(provider, gameName);// versions: [{ version, manifestHash, registeredAt, deprecated, isLatest }, ...]useDeveloperProfile
Section titled “useDeveloperProfile”import { useDeveloperProfile } from '@ludus/developer-portal';import type { UseDeveloperProfileResult } from '@ludus/developer-portal';
const { profile, updateProfile, updating, loading, error } = useDeveloperProfile(provider, developerId);
// Update profile fieldsawait updateProfile({ displayName: 'New Name', bio: 'Updated bio' });Components
Section titled “Components”Thirteen React components for building the developer dashboard:
DeveloperDashboard
Section titled “DeveloperDashboard”Top-level dashboard layout combining stats, activity feed, and quick actions:
import { DeveloperDashboard } from '@ludus/developer-portal';import type { DeveloperDashboardProps } from '@ludus/developer-portal';
<DeveloperDashboard submissionProvider={submissionProvider} revenueProvider={revenueProvider} analyticsProvider={analyticsProvider} developerId="dev-123"/>StatCard
Section titled “StatCard”Displays a single metric with label, value, and optional trend indicator:
import { StatCard } from '@ludus/developer-portal';<StatCard label="Total Revenue" value="$12,450" trend="+8%" />RevenueChart
Section titled “RevenueChart”Time series chart of revenue data:
import { RevenueChart } from '@ludus/developer-portal';<RevenueChart timeSeries={timeSeries} period="month" />RetentionChart
Section titled “RetentionChart”Visualizes D1/D7/D30 player retention metrics:
import { RetentionChart } from '@ludus/developer-portal';<RetentionChart retention={{ d1: 0.45, d7: 0.28, d30: 0.12 }} />Submission Components
Section titled “Submission Components”import { SubmissionList, SubmissionDetail, QualityGateReport } from '@ludus/developer-portal';
// List all submissions<SubmissionList submissions={submissions} onSelect={handleSelect} />
// Single submission detail with quality gate results<SubmissionDetail submission={submission} />
// Quality gate breakdown<QualityGateReport report={submission.qualityGateReport} />Game Components
Section titled “Game Components”import { GameCard, GameAnalyticsPanel } from '@ludus/developer-portal';
<GameCard game={game} onClick={handleClick} /><GameAnalyticsPanel analytics={analytics} period="week" />Payout Components
Section titled “Payout Components”import { PayoutHistory, PayoutRequestForm } from '@ludus/developer-portal';
<PayoutHistory payouts={payouts} /><PayoutRequestForm pendingAmount={pendingAmount} onRequest={requestPayout} requesting={requesting} />Version & Profile
Section titled “Version & Profile”import { VersionTimeline, DeveloperProfile } from '@ludus/developer-portal';
<VersionTimeline versions={versions} /><DeveloperProfile profile={profile} onUpdate={updateProfile} />Firestore Services
Section titled “Firestore Services”Firebase Initialization
Section titled “Firebase Initialization”import { initFirebase, getDb, setDb, resetFirebase } from '@ludus/developer-portal';import type { FirebaseConfig, EmulatorConfig } from '@ludus/developer-portal';
initFirebase({ apiKey: '...', projectId: 'ludus-dev', // ...});
const db = getDb();Converters
Section titled “Converters”Firestore document converters for type-safe reads and writes:
import { developerProfileConverter, portalSubmissionConverter, portalPayoutConverter, gameAnalyticsConverter, portalVersionEntryConverter,} from '@ludus/developer-portal';
// Usage with Firestoreconst ref = doc(db, 'developers', devId).withConverter(developerProfileConverter);Data Types
Section titled “Data Types”import type { // Time TimePeriod, // 'day' | 'week' | 'month' TimeSeriesPoint, // { date, value }
// Profile DeveloperProfileData, // { id, displayName, bio?, walletAddress, totalGamesPublished, ... }
// Submissions PortalSubmission, // { id, gameTypeId, gameName, version, status, qualityGateReport, ... } GateResult, // { name, passed, score, details, executionTimeMs } QualityGateReportData, // { gates, overallPassed, executionTimeMs }
// Revenue RevenueSummary, // { totalFees, developerShare, protocolShare, pendingPayout, currency } PortalPayout, // { id, amount, protocolAmount, currency, status, txHash?, ... }
// Analytics GameAnalytics, // { gameId, gamesPlayed, uniquePlayers, retention, revenue, ... } RetentionMetrics, // { d1, d7, d30 } ActivityItem, // { id, type, message, timestamp, gameId? } DeveloperOverview, // { totalGamesPublished, totalRevenue, totalPlayers, pendingPayout, recentActivity }
// Versions PortalVersionEntry, // { version, manifestHash, registeredAt, deprecated, isLatest }} from '@ludus/developer-portal';
// Re-exported from @ludus/game-protocolimport type { SubmissionStatus, PayoutStatus, GameCategory } from '@ludus/developer-portal';