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

# client.setupAuth()

> Present the auth frame and drive the customer through email/OTP authentication.

`client.setupAuth()` is the lighter-weight counterpart to
[`client.connect()`](/platform/sdk-reference/react-native/connect) for headless
and Identity API integrations. It drives the customer through email/OTP
authentication only, without the full connect UI, then delivers encrypted
credentials on completion.

The provider presents the auth frame in a full-screen modal. For an inline
alternative, render
[`<MoonPayAuth>`](/platform/sdk-reference/react-native/components/moonpay-auth)
instead.

**Precondition:** a `clientToken` must be present in the client context before
calling this method. The token is populated automatically when
[`client.getConnection()`](/platform/sdk-reference/react-native/get-connection)
resolves with `status: "connectionRequired"`. If no token is present,
`setupAuth()` resolves immediately with
`err({ kind: "configurationError", ... })` without mounting a frame.

```tsx AuthFlow.tsx theme={null}
import { useMoonPay, type AuthEvent } from "@moonpay/platform-sdk-react-native";

export function AuthFlow() {
  const { client } = useMoonPay();

  const startAuth = async () => {
    // Ensure the client context has a clientToken first.
    const connectionResult = await client.getConnection();
    if (!connectionResult.ok) {
      console.error(connectionResult.error.message);
      return;
    }
    if (connectionResult.value.status !== "connectionRequired") {
      // Already connected — no auth step needed.
      return;
    }

    const authResult = await client.setupAuth({
      onEvent: (event: AuthEvent) => {
        switch (event.kind) {
          case "ready":
            break;
          case "complete":
            // Emitted only for active or termsAcceptanceRequired connections.
            // Credentials are already applied to the client.
            console.log(event.payload.status);
            break;
          case "error":
            console.error(event.payload.code, event.payload.message);
            break;
        }
      },
    });

    if (!authResult.ok) {
      console.error(authResult.error.kind, authResult.error.message);
      return;
    }

    const authFrame = authResult.value;

    // You can dispose the frame at any time:
    // authFrame.dispose();
  };

  // ...
}
```

***

## Parameters

| Property  | Type                         | Required | Description                                                           |
| --------- | ---------------------------- | -------- | --------------------------------------------------------------------- |
| `onEvent` | `(event: AuthEvent) => void` |          | Callback invoked for auth flow events. See [`AuthEvent`](#authevent). |

### `AuthEvent`

`onEvent` receives events as the auth flow progresses. Use `event.kind` to
decide how to handle each event.

| kind         | Payload           | When you receive it                                                                                         |
| ------------ | ----------------- | ----------------------------------------------------------------------------------------------------------- |
| `"ready"`    | —                 | The auth UI is rendered and ready to be shown.                                                              |
| `"complete"` | `Connection`      | Emitted only when the connection is `active` or `termsAcceptanceRequired`. Credentials are already applied. |
| `"error"`    | `ConnectionError` | The flow encountered an error.                                                                              |

**`ConnectionError`** is discriminated by `code`:

| `code`              | Extra fields                           | Description                                               |
| ------------------- | -------------------------------------- | --------------------------------------------------------- |
| `"validationError"` | `errors: ConfigValidationFieldError[]` | One or more session/client/public-key fields are invalid. |
| `"generic"`         | `message?: string`                     | A generic connection failure.                             |

`ConfigValidationFieldError` entries have `code:
"invalidSessionToken" | "invalidClientToken" | "invalidPublicKey"` and a
developer-facing `message`.

## Result

`client.setupAuth()` returns a `Result<AuthFrame, SetupAuthError>`.

### Result envelope

`Result<AuthFrame, SetupAuthError>`

| Field   | Type                                | Required | Description                      |
| ------- | ----------------------------------- | -------- | -------------------------------- |
| `ok`    | `boolean`                           | ✅        | Whether the operation succeeded. |
| `value` | [`AuthFrame`](#authframe)           |          | Present when `ok` is `true`.     |
| `error` | [`SetupAuthError`](#setupautherror) |          | Present when `ok` is `false`.    |

### `AuthFrame`

| Field     | Type         | Required | Description                                      |
| --------- | ------------ | -------- | ------------------------------------------------ |
| `dispose` | `() => void` | ✅        | Unmounts the frame and detaches event listeners. |

### `SetupAuthError`

`SetupAuthError` covers failures to mount the frame, a missing `clientToken`,
customer dismissal, and in-frame errors. Per-flow errors inside the frame
surface with full details through the `"error"` event; the method then resolves
with a generic `SetupAuthError`.

| Field     | Type                                       | Required | Description                 |
| --------- | ------------------------------------------ | -------- | --------------------------- |
| `kind`    | `"configurationError"` \| `"genericError"` | ✅        | The error category.         |
| `message` | `string`                                   | ✅        | Developer-friendly details. |

`"configurationError"` is returned when no `clientToken` is present in the
client context. `"genericError"` is returned when the customer dismisses the
modal (`message: "Auth flow dismissed"`), when the frame emits an `"error"`
event, or when the frame fails to load.

```ts types.ts theme={null}
type AuthFrame = {
  dispose: () => void;
};

type SetupAuthError = {
  kind: "configurationError" | "genericError";
  message: string;
};
```
