# Player — `client.player` `PlayerDomain` (source: `src/domains/PlayerDomain.ts`) — the observable player profile: player, linked identities, currency wallets and number counters. Synced under revision key `profile`. There is no separate wallet service in this SDK. Wallet balances are read from the profile and are credited/debited server-side (admin wallet adjust, module functions). ## Surface `client.player` is a `SyncedState`: ```ts client.player.value // PlayerProfile | undefined client.player.status // 'idle' | 'loading' | 'ready' | 'error' client.player.onChange((snapshot) => { /* fires immediately */ }); await client.player.load(); await client.player.reload(); // force refetch ``` ## Types ```ts interface PlayerProfile { counters?: { [slug: string]: number }; // client-visible number counters identities?: PlayerProfileIdentity[]; player?: Player; wallets?: Wallet[]; } interface PlayerProfileIdentity { createdAt: string; provider: string; // 'device' | 'google' | 'apple' | 'custom' | 'custom:' subject: string; } interface Player { createdAt?: string; id?: string; language?: string; nickname?: string; projectId?: string; region?: string; } interface Wallet { balance?: number; currency?: string; // currency code configured in the dashboard } ``` ## Behavior notes - `counters` holds the values of `number` counters whose definition is `client_visible`; hidden counters are left out. Currency counters are in `wallets`, not in `counters`. Counter changes bump the `profile` revision. - Warmed automatically at login (with catalog). - Kept fresh by the revision poll; call `reload()` after a module function that changes wallets or counters. - All fields are optional on the wire (`?`); code defensively. - React: `useSyncExternalStore` maps directly onto `onChange` (see the SDK README "React recipe").