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

# Expo / React Native

> Wire KavachOS auth into React Native and Expo apps with @kavachos/expo. Stores tokens in AsyncStorage or SecureStore and authenticates via Authorization header.

`@kavachos/expo` brings KavachOS auth to React Native and Expo apps. It stores session tokens in any storage adapter you choose. AsyncStorage, SecureStore, or your own, and sends them via `Authorization` header rather than cookies.

## Installation

```bash theme={"system"}
npm install @kavachos/expo
# or
pnpm add @kavachos/expo
```

You also need a storage library. The most common choices:

```bash theme={"system"}
npx expo install @react-native-async-storage/async-storage
# or for encrypted storage
npx expo install expo-secure-store
```

## Setup

<Steps>
  <Step>
    ### Wrap your app

    ```tsx theme={"system"}
    // app/_layout.tsx (Expo Router) or App.tsx
    import { KavachExpoProvider } from '@kavachos/expo';
    import AsyncStorage from '@react-native-async-storage/async-storage';

    export default function RootLayout() {
      return (
        <KavachExpoProvider
          config={{
            basePath: 'https://api.myapp.com/api/kavach',
            storage: AsyncStorage,
          }}
        >
          <Stack />
        </KavachExpoProvider>
      );
    }
    ```

    The `storage` prop accepts any object with `getItem`, `setItem`, and `removeItem` methods, the same interface as `AsyncStorage` and `expo-secure-store`.
  </Step>

  <Step>
    ### Use the hooks

    ```tsx theme={"system"}
    import { useSignIn, useUser } from '@kavachos/expo';

    export function LoginScreen() {
      const { signIn, isLoading, error } = useSignIn();

      async function handleLogin() {
        const result = await signIn('user@example.com', 'password');
        if (result.success) {
          router.replace('/home');
        }
      }

      return (
        <View>
          <Button onPress={handleLogin} disabled={isLoading} title="Sign in" />
          {error && <Text>{error}</Text>}
        </View>
      );
    }
    ```
  </Step>
</Steps>

## Secure token storage

For production apps, use `expo-secure-store` to encrypt the session token at rest:

```tsx theme={"system"}
import * as SecureStore from 'expo-secure-store';
import { KavachExpoProvider } from '@kavachos/expo';

const secureStorage = {
  getItem: (key: string) => SecureStore.getItemAsync(key),
  setItem: (key: string, value: string) => SecureStore.setItemAsync(key, value),
  removeItem: (key: string) => SecureStore.deleteItemAsync(key),
};

<KavachExpoProvider config={{ basePath: '...', storage: secureStorage }}>
  {children}
</KavachExpoProvider>
```

## OAuth (deep link redirect)

For OAuth flows in Expo, use the `oauth-proxy` plugin on your server alongside `Linking.openURL` on the client:

```tsx theme={"system"}
import { Linking } from 'react-native';

async function signInWithGitHub() {
  const authUrl = 'https://api.myapp.com/api/kavach/auth/oauth/github/authorize';
  await Linking.openURL(authUrl);
  // Handle the redirect via Linking.addEventListener or expo-linking
}
```

## Hooks reference

### `useSession`

```tsx theme={"system"}
const { session, isLoading, refresh } = useSession();
```

### `useUser`

```tsx theme={"system"}
const { user, isLoading, isAuthenticated } = useUser();
```

### `useSignIn`

```tsx theme={"system"}
const { signIn, isLoading, error } = useSignIn();
const result = await signIn(email, password);
```

### `useSignUp`

```tsx theme={"system"}
const { signUp, isLoading, error } = useSignUp();
const result = await signUp(email, password, name);
```

### `useSignOut`

```tsx theme={"system"}
const { signOut } = useSignOut();
await signOut(); // clears stored token and calls server sign-out
```

### `useAgents`

```tsx theme={"system"}
const { agents, create, revoke, rotate, isLoading, error } = useAgents(basePath);
```

Manages agent identity records for the current user. Requires the full base URL (same as the provider config).

## `KavachExpoConfig`

| Field      | Type             | Description                                      |
| ---------- | ---------------- | ------------------------------------------------ |
| `basePath` | `string`         | Full URL to your KavachOS mount point            |
| `storage`  | `KavachStorage?` | Token persistence adapter. Defaults to in-memory |

<Warning>
  The default in-memory storage loses the session when the app restarts. Always pass a real storage adapter in production.
</Warning>
