> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# `useOpenfortClient`

Access the underlying Openfort client for advanced operations. It returns the same `@openfort/openfort-js` instance that `OpenfortProvider` created, so reach for it only when a namespaced SDK method has no hook equivalent.

## Usage

```tsx
import { useOpenfortClient } from '@openfort/react-native';
import { Button } from 'react-native';

function SyncProfileButton() {
  const client = useOpenfortClient();

  const syncProfile = async () => {
    const token = await client.getAccessToken();
    if (!token) return;

    await fetch('https://your-api.com/profile', {
      method: 'POST',
      headers: { Authorization: `Bearer ${token}` },
    });
  };

  return <Button title="Sync profile" onPress={() => void syncProfile()} />;
}
```

## Return type

Returns the `OpenfortClient` instance (exported from `@openfort/react-native` as an alias of the `Openfort` class in `@openfort/openfort-js`).

| Member | Type | Description |
|--------|------|-------------|
| `auth` | `AuthApi` | Email, OTP, OAuth, and guest authentication, plus `logout()`. |
| `embeddedWallet` | `EmbeddedWalletApi` | `create`, `recover`, `import`, `list`, `signMessage`, `signTypedData`, `exportPrivateKey`, `getEmbeddedState`. |
| `user` | `UserApi` | `get()` fetches the current user from the API. |
| `funding` | `FundingApi` | Cross-chain deposit sessions, also exposed through [`useFunding`](https://www.openfort.io/docs/products/embedded-wallet/react-native/wallet/funding). |
| `getAccessToken()` | `Promise<string \| null>` | The current access token, or `null` when none is available. |
| `validateAndRefreshToken(forceRefresh?)` | `Promise<void>` | Validates the access token and refreshes it when needed. |

## Keeping provider state in sync

The client writes to its own storage, not to React state. Calls that change the session therefore leave the provider's `user`, and every hook derived from it, stale until the provider refreshes.

:::warning
Do not call `client.auth.logout()` directly. [`useSignOut`](https://www.openfort.io/docs/products/embedded-wallet/react-native/hooks/useSignOut) calls it and then refreshes the provider's user state, so `useUser` and `AuthBoundary` react to the sign out.
:::

The same applies to reads: `client.user.get()` returns the freshest profile but does not update `user` from [`useUser`](https://www.openfort.io/docs/products/embedded-wallet/react-native/hooks/useUser). For rendering, keep using the hook.

## Client identity

The provider keeps one client per configuration. It rebuilds the client only when `publishableKey`, `walletConfig`, `overrides`, or `thirdPartyAuth` change in content — passing a fresh inline object with the same values on every render does not, because rebuilding tears down the embedded wallet connection. Callback props such as `getEncryptionSession` are excluded from that comparison, so they can keep per-render identity.

## Related

* [`useOpenfort`](https://www.openfort.io/docs/products/embedded-wallet/react-native/hooks/useOpenfort) — Wait for `isReady` before calling client methods
* [`useUser`](https://www.openfort.io/docs/products/embedded-wallet/react-native/hooks/useUser) — `getAccessToken` for the common token case
* [User session and authorization](https://www.openfort.io/docs/products/embedded-wallet/server/access-token) — Verifying the access token on your backend
