# Authentication and player profile

Namespace `RudderSdk.Core`. Verified against the bundled `Rudder.Core.dll`
and `Samples~/Authentication/AuthenticationSample.cs`.

## Sign in

```csharp
var client = Rudder.Initialize();
await client.Auth.LoginWithDeviceAsync("global", "en", nickname: "Player");
```

`AuthService.LoginWithDeviceAsync(string region, string language,
string nickname = null, CancellationToken cancellationToken = default)`
returns `LoginViaDeviceResponse` (`AccessToken`, `RefreshToken`). Tokens are
saved to PlayerPrefs by the Unity adapter. Pending scenario effects are
fetched after sign-in by the effects heartbeat.

Auth service:

- `Task<LoginViaDeviceResponse> LoginWithDeviceAsync(string region, string language, string nickname = null, CancellationToken = default)`
- `Task<bool> RefreshAsync()` — explicit token refresh.
- `void Logout()` — clears tokens locally.
- `event Action<RudderAuthState> AuthStateChanged` — `RudderAuthState.SignedIn` / `SignedOut`. `SignedOut` also fires when a refresh fails.

Login uses the SDK device id from PlayerPrefs. Do not pass
`SystemInfo.deviceUniqueIdentifier`.

## Profile and wallets

```csharp
var profile = await client.Player.GetProfileAsync();
var nickname = profile.Player.Nickname;
foreach (var wallet in profile.Wallets)
    Debug.Log($"{wallet.Currency}: {wallet.Balance}");
```

- `Task<PlayerProfile> PlayerService.GetProfileAsync(CancellationToken = default)`
- `PlayerProfile` — `Player Player`, `List<Wallet> Wallets`.
- `Player` — `Id`, `ProjectId`, `Nickname`, `Region`, `Language`,
  `CreatedAt` (`DateTimeOffset?`).
- `Wallet` — `Currency` (string), `Balance` (`long?`).

Models are nullable since 0.4.0 — check fields before use. After any
purchase or reward grant, reload the profile to see new wallet balances;
there is no change callback.
