// ── Unified Event (returned by /events/upcoming, /sports/events/:league, /esports/matches/upcoming) ── export interface Opponent { name: string | null; imageUrl: string | null; score: number | null; } export interface EventMedia { poster: string | null; thumbnail: string | null; streams: EventStream[]; } export interface EventStream { url: string | null; language: string | null; } export interface EventMeta { matchType: string | null; numberOfGames: number | null; tournament: string | null; country: string | null; } export interface UnifiedEvent { id: string; type: 'sports' | 'esports'; title: string; league: string | null; game: string | null; startTime: string | null; status: 'upcoming' | 'live' | 'finished' | 'canceled'; tier: string | null; venue: string | null; opponents: Opponent[]; media: EventMedia; meta: EventMeta; } export interface Pagination { page: number; perPage: number; total: number; totalPages: number; } // ── Esports Match Detail (returned by /esports/matches/:matchId) ── export interface EsportsMatchOpponent { id: number; name: string; acronym: string | null; imageUrl: string | null; } export interface EsportsMatchResult { teamId: number; score: number; } export interface EsportsMatchDetail { matchId: number; title: string; status: string; videogame: string | null; league: string | null; serie: string | null; tournament: string | null; tier: string | null; startTime: string | null; endTime: string | null; matchType: string | null; numberOfGames: number | null; opponents: EsportsMatchOpponent[]; results: EsportsMatchResult[]; winnerId: number | null; } // ── Validate Event ── export interface ValidateEventResult { bettable: boolean; gameMode: number; lockTimestamp: number; startTime: string | null; status: string; } // ── Create Game ── export interface CreateGameParams { id: string; playerWallet: string; teamChoice: 'home' | 'away' | 'draw'; wagerAmount: number; /** * When true, fund create+join with one of the user's active 0.01 SOL * streak credits instead of paying rent + buy-in from their own * wallet. SDK picks the oldest credit (FIFO). Treasury covers rent * + buy-in; player only signs to consent. Buy-in is forced to the * credit amount. */ useCredit?: boolean; } export interface CreateGameResult { gameId: string; gameAddress: string; transaction: string; lockTimestamp: number; event: UnifiedEvent; /** Set when sponsored — echoed back to confirmGame for mark-as-used. */ promoCode?: string; sponsorWallet?: string; /** Server-confirmed wager amount (== credit amount when sponsored). */ wagerAmount?: number; } // ── Custom Game (game_mode=6) ── export interface CreateCustomGameParams { playerWallet: string; teamChoice: 'home' | 'away'; wagerAmount: number; title?: string; maxPlayers?: number; metadata?: Record; } export interface CreateCustomGameResult { gameId: string; gameAddress: string; transaction: string; lockTimestamp: number; } // ── Join Game ── export interface JoinGameParams { playerWallet: string; gameId: string; teamChoice: 'home' | 'away' | 'draw'; amount: number; /** * When true, spend one of the user's active 0.01 SOL streak credits * instead of paying buy-in from the player's own wallet. The SDK * picks the oldest credit (FIFO). The treasury covers buy-in + tx * fee; the player only signs to consent. No-op if the user has no * active credits — call useCredits() to check before enabling. */ useCredit?: boolean; } export interface JoinGameResult { gameId: string; transaction: string; gameAddress: string; /** * Set when this join was sponsored. The mutation hook echoes this * back to confirmGame so the server can mark the credit as used. */ promoCode?: string; sponsorWallet?: string; } // ── Confirm Game ── export interface ConfirmGameParams { gameId: string; playerWallet: string; signature: string; teamChoice?: 'home' | 'away' | 'draw'; wagerAmount?: number; role?: 'creator' | 'joiner'; gameAddress?: string; /** Echoed back from a sponsored joinGame so the server marks the credit as used. */ promoCode?: string; } export interface ConfirmGameResult { gameId: string; signature: string; explorerUrl: string; message: string; } // ── Build Claim Transaction ── export interface BuildClaimParams { playerWallet: string; gameId: string; } export interface BuildClaimResult { transaction: string; gameAddress: string; message: string; } // ── Confirm Claim ── export interface ConfirmClaimParams { playerWallet: string; signature: string; amountClaimed?: number; } export interface ConfirmClaimResult { gameId: string; signature: string; explorerUrl: string; message: string; } // ── Game Detail (returned by /games/:gameId) ── export interface GameMedia { poster: string | null; thumbnail: string | null; } export interface Bettor { wallet: string; username: string | null; avatar: string | null; team: 'home' | 'away' | 'draw'; amount: number; amountClaimed: number | null; claimSignature: string | null; } export interface GameDetail { gameId: string; gameAddress: string; title: string; buyIn: number; gameMode: number; isLocked: boolean; isResolved: boolean; status: string; league: string | null; lockTimestamp: number | null; /** Winning side: 'home' | 'away' | 'draw' | null (null = refund) */ winnerSide: string | null; opponents: GameListOpponent[]; bettors: Bettor[]; homePool: number; awayPool: number; drawPool: number; totalPool: number; media: GameMedia; createdAt: string; updatedAt: string; } // ── Game List Item (returned by /games) ── export interface GameListOpponent { name: string | null; imageUrl: string | null; } export interface GameListItem { gameId: string; title: string; buyIn: number; gameMode: number; isLocked: boolean; isResolved: boolean; status: string; totalPool: number; league: string | null; lockTimestamp: number | null; createdAt: string; opponents: GameListOpponent[]; media: GameMedia; } export interface GetGamesParams { wallet?: string; status?: 'open' | 'locked' | 'resolved'; limit?: number; offset?: number; } // ── Network Games Query ── export interface GetNetworkGamesParams { league?: string; exclude_wallet?: string; limit?: number; offset?: number; } // ── Upcoming Events Query ── export interface GetUpcomingEventsParams { type?: 'sports' | 'esports'; game?: string; page?: number; per_page?: number; } // ── Error Parsing ── export interface ParsedError { code: string; message: string; } export interface SolanaErrorCode { code: string; message: string; } // ── User Auth ── export interface DubsUser { walletAddress: string; username: string; avatar: string | null; myReferralCode: string | null; onboardingComplete: boolean; createdAt: string; } export interface DubsPublicUser { walletAddress: string; username: string; avatar: string | null; createdAt: string; } export interface DubsAppUser extends DubsPublicUser { firstSeenAt: string; lastSeenAt: string; } export interface NonceResult { nonce: string; message: string; } export type { DeviceInfo } from './utils/device'; export interface AuthenticateParams { walletAddress: string; signature: string; nonce: string; deviceInfo?: import('./utils/device').DeviceInfo; } export interface AuthenticateResult { needsRegistration: boolean; user?: DubsUser; token?: string; } export interface RegisterParams { walletAddress: string; signature: string; nonce: string; username: string; referralCode?: string; avatarUrl?: string; deviceInfo?: import('./utils/device').DeviceInfo; } export interface RegisterResult { user: DubsUser; token: string; } export interface CheckUsernameResult { available: boolean; reason?: string; } export type AuthStatus = | 'idle' | 'authenticating' | 'signing' | 'verifying' | 'needsRegistration' | 'registering' | 'authenticated' | 'error'; // ── Mutation Hook Status ── export type MutationStatus = | 'idle' | 'building' | 'signing' | 'confirming' | 'saving' | 'success' | 'error'; // ── Query Hook Result ── export interface QueryResult { data: T | null; loading: boolean; error: Error | null; refetch: () => void; } // ── Mutation Hook Result ── export interface MutationResult { execute: (params: TParams) => Promise; status: MutationStatus; error: Error | null; data: TResult | null; reset: () => void; } // ── Live Scores ── export interface LiveScoreCompetitor { name: string; homeAway: 'home' | 'away'; score: number; logo: string | null; abbreviation: string; } export interface LiveScore { status: string; period: number | null; displayClock: string | null; detail: string | null; shortDetail: string | null; competitors: LiveScoreCompetitor[]; ufcData?: { currentRound: number; totalRounds: number; clock: string; fightState: string; statusDetail: string; }; } // ── UFC Fight Card ── export interface UFCFighter { name: string; athleteId: string | null; headshotUrl: string | null; flagUrl: string | null; country: string | null; abbreviation: string; record: string | null; winner: boolean; } export interface UFCFighterDetail { athleteId: string; firstName: string | null; lastName: string | null; fullName: string | null; nickname: string | null; shortName: string | null; height: string | null; heightInches: number | null; weight: string | null; weightLbs: number | null; reach: string | null; reachInches: number | null; age: number | null; dateOfBirth: string | null; stance: string | null; weightClass: string | null; citizenship: string | null; citizenshipAbbreviation: string | null; gym: string | null; gymCountry: string | null; active: boolean; headshotUrl: string | null; flagUrl: string | null; stanceImageUrl: string | null; espnUrl: string | null; slug: string | null; } export interface UFCData { currentRound: number; totalRounds: number; clock: string; fightState: 'pre' | 'in' | 'post'; statusDetail: string; statusShortDetail?: string; } export interface UFCFight { id: string | null; home: UFCFighter; away: UFCFighter; weightClass: string | null; status: string; ufcData: UFCData | null; } export interface UFCEvent { eventName: string; date: string | null; fights: UFCFight[]; } // ── Arcade Pool Entry ── export interface BuildArcadeEntryResult { transaction: string; // base64-encoded unsigned transaction poolId: string; amount: string; destination?: string; gameId?: string; // on-chain game ID (set on first entry) gameAddress?: string; // game PDA address } export interface EnterArcadePoolResult { poolId: string; signature: string; entry: ArcadeEntry; } // ── Arcade Pools ── export interface ArcadePool { id: number; app_id: number; game_slug: string; name: string; buy_in_lamports: number; max_lives: number; period_start: string; period_end: string; schedule: 'weekly' | 'daily' | 'monthly'; status: 'open' | 'active' | 'resolving' | 'complete' | 'cancelled'; solana_game_id: string | null; solana_game_address: string | null; total_entries: number; created_at: string; next_resolution: string | null; } export interface ArcadeEntry { id: number; pool_id: number; wallet_address: string; best_score: number; lives_used: number; rank: number | null; created_at: string; attempts: ArcadeAttempt[] | null; } export interface ArcadeAttempt { id: number; attempt_number: number; score: number | null; status: 'active' | 'submitted' | 'expired'; started_at: string; submitted_at: string | null; duration_ms: number | null; } export interface ArcadeLeaderboardEntry { id: number; wallet_address: string; best_score: number; lives_used: number; username: string; avatar: string | null; rank: number; } export interface ArcadePoolStats { total_entries: number; top_score: number; avg_score: number; active_players: number; } export interface StartAttemptResult { sessionToken: string; attemptNumber: number; livesRemaining: number; } export interface SubmitScoreResult { score: number; bestScore: number; livesUsed: number; isNewBest: boolean; } export interface ArcadePoolResult { id: number; pool_id: number; entry_id: number; wallet_address: string; amount_lamports: string; status: string; username: string; avatar: string | null; best_score: number; } // ── Jackpot ── export interface JackpotRound { roundId: string; status: 'Open' | 'Locked' | 'Resolved'; totalPotLamports: string; totalPotSol: number; entryCount: number; totalWeight: string; timeRemainingSlots: number; } export interface JackpotLastWinner { roundId: string; winner: string; winAmount: string; winAmountSol: number; totalPot: string; entryCount: number; timestamp: string | null; } export interface JackpotEntry { player: string; weight: string; weightSol: number; oddsPercent: string; } export interface JackpotRoundResult { roundId: string; winner: string; winAmount: string; winAmountSol: number; totalPot: string; totalPotSol: number; entryCount: number; timestamp: string; } export interface JackpotConfig { feeBasisPoints: number; roundDurationSlots: string; minEntryLamports: number; minEntrySol: number; } export interface BuildJackpotEnterResult { transaction: string; roundId: string; amount: string; amountSol: number; } export interface ConfirmJackpotEnterResult { attributed: boolean; appId: number; signature: string; } // ── UI Config (developer branding) ── export interface UiConfig { accentColor?: string; appIcon?: string; appName?: string; appUrl?: string; tagline?: string; environment?: 'sandbox' | 'production'; /** * Whether the developer has uploaded push credentials in the dev portal. * Consumers should gate their push opt-in UI on the relevant platform flag — * e.g. only show the "Enable Notifications" screen if pushConfigured.android is true. */ pushConfigured?: { android: boolean; ios: boolean; }; } // ── What's New (per-app feature announcements) ── export type WhatsNewCategory = 'feature' | 'improvement' | 'bugfix' | 'announcement'; export interface WhatsNewPost { id: number; title: string; content: string; gif_url: string | null; category: WhatsNewCategory; version: string | null; is_pinned: boolean; is_published: boolean; /** Present when the post is fetched in an authenticated context. */ is_read?: boolean; created_by: string; created_at: string; updated_at: string; } /** * A single promo credit reserved to the authenticated user. Returned by * GET /me/credits and surfaced via useCredits. `source = 'streak_milestone'` * for credits auto-minted at each 1000-dub streak threshold; 'manual' for * Twitter-giveaway codes typed in during onboarding. */ export interface PromoCredit { id: number; code: string; amountLamports: number; amountSOL: number; awardedAt: string; source: 'streak_milestone' | 'manual' | string; }