> For the complete documentation index, see [llms.txt](https://city-protocol.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://city-protocol.gitbook.io/docs/software-development-kit/wallet/client-side-authentication.md).

# Client-Side Authentication

#### Reading Session State

`usePrivy` is your primary hook for login state, user metadata, and session control.

```
import { usePrivy } from "@privy-io/react-auth";

const { ready, authenticated, login, logout, user } = usePrivy();
```

| Property        | Type      | Description                                                   |
| --------------- | --------- | ------------------------------------------------------------- |
| `ready`         | `boolean` | `true` once the Privy SDK has finished initialising           |
| `authenticated` | `boolean` | `true` when the user has an active session                    |
| `login`         | `fn`      | Opens the Privy login modal                                   |
| `logout`        | `fn`      | Ends the session and clears local state                       |
| `user`          | `object`  | Contains `wallet.address`, linked accounts, and Privy user ID |

#### Obtaining the Identity Token

`useIdentityToken` returns a short-lived JWT that represents the authenticated session. This is the token your backend verifies.

```
import { useIdentityToken } from "@privy-io/react-auth";

const { identityToken } = useIdentityToken();
```

Send it to your backend as a Bearer token in the `Authorization` header. Do **not** store it in `localStorage`; the hook manages refresh automatically.

#### Full Component Example

```
import { useIdentityToken, usePrivy } from "@privy-io/react-auth";

export function WalletGate() {
  const { ready, authenticated, login, logout, user } = usePrivy();
  const { identityToken } = useIdentityToken();

  if (!ready) return <button disabled>Loading...</button>;
  if (!authenticated) return <button onClick={login}>Connect wallet</button>;

  async function callBackend() {
    await fetch("/api/me", {
      headers: {
        Authorization: `Bearer ${identityToken}`,
      },
    });
  }

  return (
    <div>
      <p>{user?.wallet?.address}</p>
      <button onClick={callBackend}>Call backend</button>
      <button onClick={logout}>Disconnect</button>
    </div>
  );
}
```
