54 lines
1.5 KiB
Markdown
54 lines
1.5 KiB
Markdown
|
|
# Player profile + wallets — `client.player`
|
||
|
|
|
||
|
|
`PlayerDomain` (source: `src/domains/PlayerDomain.ts`) — the observable player
|
||
|
|
profile: identity plus currency wallets. 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 (purchases, quest/battle pass
|
||
|
|
rewards, scenario nodes).
|
||
|
|
|
||
|
|
## Surface
|
||
|
|
|
||
|
|
`client.player` is a `SyncedState<PlayerProfile>`:
|
||
|
|
|
||
|
|
```ts
|
||
|
|
client.player.data // 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 {
|
||
|
|
player?: Player;
|
||
|
|
wallets?: Wallet[];
|
||
|
|
}
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
|
- Warmed automatically at login (one of the four parallel warm loads).
|
||
|
|
- Invalidated (refetched) after every successful store purchase and after
|
||
|
|
scenario server callbacks — subscribers see fresh balances without waiting
|
||
|
|
for the revision poll.
|
||
|
|
- All fields are optional on the wire (`?`); code defensively.
|
||
|
|
- React: `useSyncExternalStore` maps directly onto `onChange` (see the SDK
|
||
|
|
README "React recipe").
|