# `useOpenfort`

:::info
If using Next.js App Router, add `"use client"` at the top of the file.
:::

Access the core Openfort context, including the SDK client instance, embedded wallet state, and user information.

:::warning
This hook provides low-level access to the Openfort SDK. For most use cases, prefer using the specialized hooks like [`useUser`](/docs/products/embedded-wallet/react/hooks/useUser), [`useEthereumEmbeddedWallet`](/docs/products/embedded-wallet/react/hooks/useEthereumEmbeddedWallet), [`useSolanaEmbeddedWallet`](/docs/products/embedded-wallet/react/hooks/useSolanaEmbeddedWallet), or the authentication hooks.
:::

## Usage

```tsx
import { useOpenfort } from '@openfort/react';

function AdvancedComponent() {
  const { client, embeddedState, user, isLoading } = useOpenfort();

  // Access the underlying Openfort SDK client for advanced operations
  const handleAdvancedOperation = async () => {
    const accessToken = await client.getAccessToken();
    // Use the token for custom API calls
  };

  if (isLoading) return <div>Loading...</div>;

  return (
    <div>
      <p>Embedded state: {embeddedState}</p>
      <p>User ID: {user?.id}</p>
      <button onClick={handleAdvancedOperation}>
        Get Access Token
      </button>
    </div>
  );
}
```

## Return type

The hook returns the core Openfort context value (`OpenfortCoreContextValue`):

```ts
import type {
  ChainTypeEnum,
  EmbeddedAccount,
  EmbeddedState,
  Openfort,
  OpenfortError,
  User,
} from '@openfort/openfort-js'
import type { UserAccount } from '@openfort/react'

type UseOpenfortReturn =  {
    // The Openfort SDK client instance
  client: Openfort
  // Current chain type (EVM | SVM)
  chainType: ChainTypeEnum
  setChainType: (chainType: ChainTypeEnum) => void
  // Sign up as guest user
  signUpGuest: () => Promise<void>
  // Current embedded wallet state
  embeddedState: EmbeddedState

  // Whether the SDK is loading/initializing
  isLoading: boolean
  // Whether wallet recovery is needed
  needsRecovery: boolean
  // Current authenticated user
  user: User | null
  // Update the user object
  updateUser: (user?: User) => Promise<User | null>
  // Linked authentication accounts (external wallets and auth providers only, not embedded wallets)
  linkedAccounts: UserAccount[]

  // Embedded wallet accounts
  embeddedAccounts?: EmbeddedAccount[]
  // Whether embedded accounts are loading
  isLoadingAccounts: boolean
  // Current active embedded wallet address. Set by useEthereumEmbeddedWallet.setActive and synced from SDK on load.
  activeEmbeddedAddress: string | undefined
  setActiveEmbeddedAddress: (address: string | undefined) => void

  // Sign out the current user
  logout: () => void

  // Refresh embedded accounts data
  updateEmbeddedAccounts: (options?: { silent?: boolean }) => Promise<EmbeddedAccount[] | undefined>

  // Current wallet flow status
  walletStatus: WalletFlowStatus
  // Update wallet flow status
  setWalletStatus: (status: WalletFlowStatus) => void

  // Set when auto-recovery fails. Null on success or when cleared by a new auth session.
  // Use this to show recovery error UI.
  recoveryError: Error | null
}

// Embedded wallet states
enum EmbeddedState {
  NONE = 0,
  UNAUTHENTICATED = 1,
  EMBEDDED_SIGNER_NOT_CONFIGURED = 2,
  CREATING_ACCOUNT = 3,
  READY = 4,
}

type WalletFlowStatus =
  | { status: 'idle'; error?: never }
  | { status: 'awaiting-input'; error?: never }
  | { status: 'loading'; error?: never }
  | { status: 'success'; error?: never }
  | { status: 'error'; error: OpenfortError | null }
  | { status: 'creating' | 'connecting'; address?: `0x${string}`; error?: never }
```

## Store selectors (advanced)

The SDK exports store selectors and context for advanced usage with the underlying zustand store:

* `StoreContext` — React context providing access to the `OpenfortStore`
* `useOpenfortCore` — Low-level hook for direct store access
* `selectActiveAddress` — Selector for the active wallet address
* `selectChainType` — Selector for the current chain type
* `selectEmbeddedState` — Selector for the embedded wallet state
* `selectIsAuthenticated` — Selector for authentication status
* `selectIsLoading` — Selector for loading status
* `selectUser` — Selector for the current user
* `selectWalletStatus` — Selector for wallet flow status

These are exported from `@openfort/react` and can be used for performance-sensitive components that need to subscribe to specific slices of state.

## Example: Custom API calls with access token

```tsx
import { useOpenfort } from '@openfort/react';

function CustomApiExample() {
  const { client } = useOpenfort();

  const fetchUserData = async () => {
    const accessToken = await client.getAccessToken();

    const response = await fetch('https://your-api.com/user-data', {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      },
    });

    return response.json();
  };

  return <button onClick={fetchUserData}>Fetch Data</button>;
}
```

## Example: Check embedded wallet state

```tsx
import { useOpenfort } from '@openfort/react'
import { EmbeddedState } from '@openfort/openfort-js'

function WalletStateChecker() {
  const { embeddedState, needsRecovery } = useOpenfort();

  const getStateMessage = () => {
    switch (embeddedState) {
      case EmbeddedState.NONE:
        return 'No wallet configured';
      case EmbeddedState.UNAUTHENTICATED:
        return 'Please sign in';
      case EmbeddedState.EMBEDDED_SIGNER_NOT_CONFIGURED:
        return 'Wallet signer not configured';
      case EmbeddedState.CREATING_ACCOUNT:
        return 'Creating wallet...';
      case EmbeddedState.READY:
        return needsRecovery ? 'Wallet needs recovery' : 'Wallet ready';
      default:
        return 'Unknown state';
    }
  };

  return <p>{getStateMessage()}</p>;
}
```
