> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Session & Profile Hooks

> Provider access, sign-in, session refresh and the signed-in user's profile.

## useMonacoSDK

```tsx theme={null}
import { useMonacoSDK } from "@0xmonaco/react";

const { 
  sdk,
  clientId,
  error,
  clearError,
  setError
} = useMonacoSDK();
```

**sdk** `MonacoSDK | null`

Monaco SDK instance (null while initializing)

**clientId** `string`

Application client ID from provider

**error** `Error | null`

SDK initialization error if any

**clearError** `() =\> void`

Clear the current error

**setError** `(error: Error | null) =\> void`

Set an error state

## useAuth

```tsx theme={null}
import { useAuth } from "@0xmonaco/react";

const {
  authenticationStatus,
  login,
  logout,
  refreshAuth,
  refreshSession,
  revokeSession,
  requestInviteCodes,
  listInviteCodes,
  authenticate,
  signChallenge,
  createChallenge
} = useAuth();
```

`useAuth` wraps the SDK's wallet-authorized session-key flow. `login()` generates a session key, prompts the wallet once, and (via the provider) persists the session; every subsequent request is signed automatically. There are no access or refresh tokens. See [TypeScript authentication](https://docs.0xmonaco.com/sdk/typescript/auth.md) for the lower-level SDK model.

### Authentication State

**authenticationStatus** `AuthenticationStatus`

Current authentication state:

* `"unauthenticated"` - Not logged in
* `"authenticating"` - Login in progress
* `"authenticated"` - Session active

### Core Actions

**login** `(options?: \{ connectWebSocket?: boolean; inviteCode?: string \}) =\> Promise\<AuthState\>`

Authenticate the user with a wallet signature, using the address and `clientId` from context. Returns an `AuthState` (with the session keypair).

**Options:**

* `connectWebSocket`: Auto-connect authenticated WebSocket channels after login (default: `false`). Public channels (OHLCV, Orderbook, Trades) don't require authentication.
* `inviteCode`: A Mainnet invite code: exactly 10 case-sensitive letters or digits. Needed while Mainnet invite mode is on for a wallet without Mainnet access; not redeemed otherwise. A sign-in that needs one is refused with `403` and `serverCode` `INVITE_CODE_REQUIRED` — see [Invite Codes](https://docs.0xmonaco.com/developers/invite-codes.md).

```tsx theme={null}
const authState = await login();
const withSockets = await login({ connectWebSocket: true });
const withCode = await login({ inviteCode: codeFromUser });
```

**logout** `() =\> Promise\<void\>`

Revoke the session on the server and clear local auth state.

**refreshAuth** `() =\> Promise\<AuthState\>`

Extend the current session's expiry. The keypair is unchanged; returns the updated `AuthState`.

### Session Actions

**refreshSession** `() =\> Promise\<SessionRefreshResponse\>`

Lower-level refresh that returns just the new `expiresAt`. `refreshAuth()` wraps this and updates the stored `AuthState`.

**revokeSession** `() =\> Promise\<void\>`

Revoke the current session on the server without clearing local React state (`logout()` does both).

### Invite Codes

**requestInviteCodes** `() =\> Promise\<InviteCodeRequestSummary\>`

Mint one Mainnet invite code from the signed-in wallet's allowance; each call uses up a slot. Wraps `sdk.auth.requestInviteCodes()` — see [Mainnet Invite Codes](https://docs.0xmonaco.com/sdk/typescript/auth.md#mainnet-invite-codes) for the response and errors.

**listInviteCodes** `() =\> Promise\<InviteCodeList\>`

Read the signed-in wallet's invite allowance and the codes it minted, without using a slot. Wraps `sdk.auth.listInviteCodes()`.

See [Invite Codes](https://docs.0xmonaco.com/developers/invite-codes.md) for the sign-in and sharing flows.

### Advanced Building Blocks

`login` / `authenticate` run these internally and manage the session keypair for you. Use them directly only for custom flows.

**authenticate** `() =\> Promise\<AuthState\>`

The programmatic equivalent of `login()` — generates the session key, prompts the wallet, verifies, and returns the `AuthState`.

**signChallenge** `(message: string) =\> Promise\<string\>`

Ask the connected wallet to authorize a challenge message. Returns a hex signature — EIP-191 from an EOA, or an EIP-1271 contract signature from a smart-contract wallet such as a Safe. Submit it unchanged; do not assume the 65-byte EOA shape. Server-side EIP-1271 verification is deliberately narrow: it is offered only to a wallet holding a BuilderCodes payout bucket, on a deployment with the contract-wallet flag on and a chain RPC endpoint configured. An ordinary smart-contract trading account is NOT covered — it still takes the recovery path and cannot authenticate.

**createChallenge** `(address: string, sessionPublicKey: string) =\> Promise\<ChallengeResponse\>`

Create a single-use challenge whose message embeds the given session public key. Returns `nonce`, `message`, and `expiresAt`.

### Example: Login Button

```tsx theme={null}
import { useAuth } from "@0xmonaco/react";

function LoginButton() {
  const { login, authenticationStatus } = useAuth();

  const handleLogin = async () => {
    try {
      const authState = await login();
      console.log('Logged in:', authState.user);
    } catch (error) {
      if (error.message.includes('SDK not available')) {
        alert('SDK is still loading, please wait');
      } else if (error.message.includes('Wallet not connected')) {
        alert('Please connect your wallet first');
      } else {
        console.error('Login failed:', error);
      }
    }
  };

  return (
    <button
      onClick={handleLogin}
      disabled={authenticationStatus === 'authenticating'}
    >
      {authenticationStatus === 'authenticating' ? 'Logging in...' : 'Login'}
    </button>
  );
}
```

> [!NOTE]
>
> Auth actions validate SDK availability, wallet connection, and required parameters before running, throwing a descriptive `Error` (e.g. `"SDK not available"`, `"Wallet not connected"`, `"Client ID is required"`) when a precondition is missing.

## useTokenLifecycle

```tsx theme={null}
import { useTokenLifecycle } from "@0xmonaco/react";

const {
  initializeTokens,
  clearTokens,
  refreshTokens,
  isTokenExpired
} = useTokenLifecycle(sdk, config);
```

Manages the lifecycle of the authenticated session: persists the session across reloads and refreshes it before it expires. The session is the wallet-authorized ed25519 keypair returned by `login()`; there are no separate access or refresh tokens. Most apps don't use this hook directly; `MonacoProvider` wires it up and `useAuth` drives it. See [React SDK setup](https://docs.0xmonaco.com/sdk/react/intro).

### Parameters

**sdk** `MonacoSDK | null` *required*

Monaco SDK instance from `useMonacoSDK()`

**config** `TokenLifecycleConfig`

Session lifecycle options:

* `autoRefresh`: boolean (default: `true`) - automatically extend the session before it expires
* `persistTokens`: boolean (default: `true`) - persist the session in `localStorage` so it survives reloads
* `refreshBufferSeconds`: number (default: `300`) - how long before expiry to trigger a refresh
* `onRefreshError`: `(error: Error) => void` - called when a refresh fails
* `onRefreshSuccess`: `(authState: AuthState) => void` - called when a refresh succeeds

### Return Values

**initializeTokens** `(authState: AuthState) =\> void`

Start managing a session. Call after a successful `login()`; persists the session (if enabled) and schedules auto-refresh.

**clearTokens** `() =\> void`

Stop managing the session, cancel scheduled refreshes, and remove the persisted session. Call on logout.

**refreshTokens** `() =\> Promise\<AuthState | null\>`

Extend the session's expiry now (via `sdk.refreshAuth()`). Returns the updated `AuthState`, or `null` if there is no active session or the refresh fails.

**isTokenExpired** `(authState: AuthState | null) =\> boolean`

Whether the session is expired or within the refresh buffer of expiry.

### Example

```tsx theme={null}
import { useMonacoSDK, useTokenLifecycle } from "@0xmonaco/react";

function SessionManager() {
  const { sdk } = useMonacoSDK();

  const {
    initializeTokens,
    clearTokens,
    refreshTokens,
    isTokenExpired
  } = useTokenLifecycle(sdk, {
    autoRefresh: true,
    persistTokens: true,
    refreshBufferSeconds: 300, // refresh 5 minutes before expiry
    onRefreshError: (error) => {
      console.error('Session refresh failed:', error);
      // Handle logout or re-authentication
    },
    onRefreshSuccess: (authState) => {
      console.log('Session extended to', authState.expiresAt);
    },
  });

  // After a successful login
  const handleLoginSuccess = (authState) => {
    initializeTokens(authState);
  };

  // On logout
  const handleLogout = () => {
    clearTokens();
  };

  // Manual refresh if needed
  const handleManualRefresh = async () => {
    const newAuthState = await refreshTokens();
    if (!newAuthState) {
      console.log('Refresh failed, need to re-authenticate');
    }
  };

  return (
    <div>
      <button onClick={handleManualRefresh}>Refresh Session</button>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
}
```

### How It Works

1. **Auto Refresh**: when enabled, schedules a session refresh `refreshBufferSeconds` before expiry.
2. **Persistence**: saves the session to `localStorage` so it can be restored after a reload.
3. **Deduplication**: collapses concurrent refresh calls into a single request.
4. **Cleanup**: clears scheduled timers on unmount.

When `persistTokens` is enabled, the persisted session includes the ed25519 **session private key**. This credential signs every request. `localStorage` is readable by any script on your origin, so harden against XSS (e.g. a strict Content Security Policy) and always `clearTokens()` on logout. Disable `persistTokens` to keep the session in memory only.

> [!NOTE]
>
> This is an advanced hook. For most apps, `MonacoProvider` + `useAuth` manage the session automatically.

## useProfile

```tsx theme={null}
import { useProfile } from "@0xmonaco/react";

const {
  profile,
  balances,
  movements,
  orders,
  loading,
  fetchProfile,
  getPaginatedUserMovements,
  getUserBalances,
  getUserBalanceByAssetId,
  getPaginatedOrders,
} = useProfile();
```

### State

**profile** `UserProfile | undefined`

Core profile metadata (id, address, username, account type, withdrawal status). Undefined until fetched. Does not include balances, movements, or orders.

**balances** `AccountBalance[]`

User's token balances. Populated by `fetchProfile()` (first 20) or `getUserBalances()`. Empty array until fetched.

**movements** `GetPaginatedUserMovementsResponse | undefined`

User's ledger movements. Populated by `fetchProfile()` (first cursor page, `pageSize` 20) or `getPaginatedUserMovements()`. Undefined until fetched.

**orders** `GetPaginatedOrdersResponse | undefined`

User's orders. Populated by `fetchProfile()` (first cursor page, pageSize 20) or `getPaginatedOrders()`. Undefined until fetched.

**loading** `boolean`

True while `fetchProfile()` is in flight. Does not reflect individual fetch method calls.

### Actions

**fetchProfile** `() =\> Promise\<UserProfile\>`

Fetches the core profile and the first page of balances, movements, and orders in parallel. Updates all state fields. Throws if the profile fetch fails; balance/movement/order fetch failures are silent (state remains unchanged for those fields).

**getUserBalances** `(params?) =\> Promise\<GetUserBalancesResponse\>`

Fetch a cursor page of token balances. Updates `balances` state.

**Parameters:**

* `pageSize` (optional): Number of items per page, 1 to 1000 (default: 20). A larger value is rejected, not clamped
* `pageToken` (optional): cursor — omit or send `""` for the first page, then pass the previous response's `nextPageToken`. The walk seeks on `(token, assetId)` over the set the server overlays with the matching engine's authoritative amounts, so a balance the engine adds mid-walk no longer appears only at the end of the last page

There is no `page`: the SDK rejects one with a `ValidationError` before sending, and a raw REST request carrying it gets `400`.

**Returns:** `balances` plus `nextPageToken` — pass it back as `pageToken` and keep going until it comes back empty.

**getUserBalanceByAssetId** `(assetId: string) =\> Promise\<AccountBalance\>`

Get the balance for a specific asset by its UUID. Does not update `balances` state.

**getPaginatedUserMovements** `(params?) =\> Promise\<GetPaginatedUserMovementsResponse\>`

Fetch paginated transaction history. Updates `movements` state.

**Parameters:**

* `pageSize` (optional): Number of items per page, 1 to 1000 (default: 20). A larger value is rejected, not clamped
* `pageToken` (optional): cursor — omit or send `""` for the first page, then pass the previous response's `nextPageToken`. The walk seeks on `(createdAt, id)`, both immutable, so a movement written mid-walk cannot make the walk repeat or drop a row
* `entryType` (optional): Filter by entry type (`LedgerEntryType`, upper-case)
* `transactionType` (optional): Filter by transaction type (`TransactionType`, upper-case)
* `assetId` (optional): Filter by asset UUID
* `orderBy` (optional): `"ASC"` or `"DESC"` (default `"DESC"`); a `pageToken` resumes only under the same `orderBy`

There is no `page`: the SDK rejects one with a `ValidationError` before sending, and a raw REST request carrying it gets `400`. The filters must match the request that minted the token.

**Returns:** `movements` plus `nextPageToken` — pass it back as `pageToken` and keep going until it comes back empty.

**getPaginatedOrders** `(params?) =\> Promise\<GetPaginatedOrdersResponse\>`

Fetch paginated orders. Updates `orders` state.

**Parameters:**

* `status`, `tradingPairId`, `tradingMode`, `marginAccountId` (optional): filters
* `pageSize` (optional): Items per page, up to 1000 (default: 10)
* `pageToken` (optional): cursor — omit or send `""` for the first page, then pass the previous response's `nextPageToken`. See [Order queries](https://docs.0xmonaco.com/sdk/typescript/trades.md#order-queries)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.