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

# Wait for Auth Success

> [card] Recommended: JavaScript SDK for React Native
>
> While this SDK is still supported, we recommend using newer [JavaScript SDK](https://docs.dynamic.xyz/docs/javascript/reference/react-native-quickstart.md), which is optimized for React Native, but also comes with a host of other benefits.

# waitForAuthSuccess

Returns a promise that resolves with the authenticated user once the `authSuccess` event fires. Use this when you need to ensure authentication is fully complete — including MFA and other intermediate steps — before proceeding (for example, before loading wallets or accessing user data).

Before this: set up the Dynamic client (see [Setting up the Dynamic Client](https://docs.dynamic.xyz/docs/react-native/reference/client.md)).

## Why use this instead of listening to events?

Listening for `authSuccess` with `dynamicClient.auth.on` works, but it requires manual cleanup and doesn't handle edge cases like MFA flows where authentication pauses for user input. `waitForAuthSuccess` wraps this into a single promise that:

* Resolves when authentication completes (even after MFA or other intermediate steps)
* Rejects when authentication fails or is cancelled
* Supports an optional timeout

## Usage

```typescript theme={"system"}
import { dynamicClient } from '<path to client file>';

const user = await dynamicClient.auth.waitForAuthSuccess();
// Authentication complete — user and wallets are available
```

## Parameters

| Parameter | Type | Description |
| - | - | - |
| `timeout` | `number` | Maximum time in milliseconds to wait. Rejects with an error if exceeded. |

Pass options as an object:

```typescript theme={"system"}
dynamicClient.auth.waitForAuthSuccess({ timeout: 60_000 });
```

## Returns

`Promise<UserProfile>` — Resolves with the authenticated user profile.

## Behavior

* **User not yet authenticated**: Listens for `authSuccess` and resolves when it fires. If `authFailed` fires first, the promise rejects.
* **User already authenticated**: Waits briefly (500 ms grace period) for an incoming `authSuccess` event. If no event arrives, resolves with the current authenticated user. This handles the case where authentication completed moments before the call.
* **Timeout**: If `timeout` is set and neither `authSuccess` nor `authFailed` fires within that window, the promise rejects with a timeout error.

## Examples

### Wait for authentication before loading wallets

> [tab] With UI auth flow
>
> ```tsx React Native theme={"system"}
> import { dynamicClient } from '<path to client file>';
> import { useState } from 'react';
> import { View, Button, Text } from 'react-native';
>
> const LoginScreen = () => {
>   const [status, setStatus] = useState('');
>
>   const handleLogin = async () => {
>     dynamicClient.ui.auth.show();
>
>     try {
>       const user = await dynamicClient.auth.waitForAuthSuccess();
>       setStatus(`Authenticated: ${user.email}`);
>       // Safe to access wallets now
>     } catch (error) {
>       setStatus(`Auth failed: ${error.message}`);
>     }
>   };
>
>   return (
>     <View>
>       <Button title="Log in" onPress={handleLogin} />
>       {status ? <Text>{status}</Text> : null}
>     </View>
>   );
> };
> ```

> [tab] With email OTP
>
> ```tsx React Native theme={"system"}
> import { dynamicClient } from '<path to client file>';
> import { useState } from 'react';
> import { View, TextInput, Button, Text } from 'react-native';
>
> const EmailLoginScreen = () => {
>   const [email, setEmail] = useState('');
>   const [otp, setOtp] = useState('');
>   const [otpSent, setOtpSent] = useState(false);
>
>   const handleSendOTP = async () => {
>     await dynamicClient.auth.email.sendOTP(email);
>     setOtpSent(true);
>   };
>
>   const handleVerifyOTP = async () => {
>     await dynamicClient.auth.email.verifyOTP(otp);
>
>     // Wait for auth to fully complete (including MFA if required)
>     const user = await dynamicClient.auth.waitForAuthSuccess();
>
>     // Now safe to check embedded wallet status
>     const hasWallet = dynamicClient.wallets.embedded.hasWallet;
>     console.log('Has embedded wallet:', hasWallet);
>   };
>
>   return (
>     <View>
>       {!otpSent ? (
>         <View>
>           <TextInput
>             value={email}
>             onChangeText={setEmail}
>             placeholder="Enter your email"
>           />
>           <Button title="Send OTP" onPress={handleSendOTP} />
>         </View>
>       ) : (
>         <View>
>           <TextInput
>             value={otp}
>             onChangeText={setOtp}
>             placeholder="Enter OTP"
>           />
>           <Button title="Verify OTP" onPress={handleVerifyOTP} />
>         </View>
>       )}
>     </View>
>   );
> };
> ```

## Error handling

The promise rejects in three cases:

| Scenario | Error message |
| - | - |
| User cancels authentication | `Authentication was cancelled by the user` |
| Authentication fails | `Authentication failed: <reason>` |
| Timeout exceeded | `waitForAuthSuccess timed out` |

## Related

* [Listening to events](https://docs.dynamic.xyz/docs/react-native/reference/hooks-events/events.md) — Subscribe to individual client events
* [Auth module events](https://docs.dynamic.xyz/docs/react-native/reference/hooks-events/events.md#auth-module) — Full list of auth events including `authSuccess` and `authFailed`
* [MFA](https://docs.dynamic.xyz/docs/react-native/authentication-methods/mfa/overview.md) — MFA flows that complete before `authSuccess` fires


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