> ## 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.

# Post-login user setup

> SyncAuthFlow is gone — migrate the automatic post-login orchestration (onboarding, MFA, device registration, wallet creation) to an explicit chain you own.

This is the biggest behavioral change in the migration. In the React SDK, `SyncAuthFlow` ran automatically after authentication and chained every remaining setup step for you. The JavaScript SDK does none of this — you decide which steps to run, detect what's pending, and render each screen.

## What SyncAuthFlow did

After a user authenticated, `SyncAuthFlow` silently orchestrated, in order:

1. Onboarding / required-field collection
2. Captcha (when enabled)
3. MFA enrollment
4. Device registration
5. Embedded wallet creation

You never called these — the widget detected what was missing (`useSyncOnboardingFlow` watched `userWithMissingInfo.missingFields`, `useSyncMfaFlow` watched MFA state, etc.) and pushed the matching view.

## What you own now

There is no automatic orchestration. After auth resolves, you run the chain yourself: check each step, show UI for whatever is pending, and let the user in once everything is done.

```
signed in → required fields? → MFA? → device registration? → embedded wallet? → ready
```

Each legacy sync hook maps to a detection call you make explicitly:

| React SDK (automatic) | JavaScript SDK (you call) |
| - | - |
| `useSyncOnboardingFlow` (required fields) | inspect `user.missingFields`, save with `updateUser({ userFields })` |
| `useSyncMfaFlow` | `isUserMissingMfaAuth()` |
| `useSyncDeviceRegistrationFlow` | `isDeviceRegistrationRequired(user)` |
| `useSyncEmbeddedWalletFlow` / `useSyncDynamicWaas` | `isDynamicWaasEnabled()` + `getChainsMissingWaasWalletAccounts()` |

> [!WARNING]
>
> Do not gate access on a single "onboarding complete" flag. Compose the per-step checks above so you control exactly which steps block entry.

## The orchestration pattern

Only handle the steps that apply to your app. Every step below is independent and optional — if your app doesn't use MFA, skip the MFA check; if it has no embedded wallets, skip wallet creation; and so on. Compose only the checks for the features you've actually enabled, in the order that fits your flow. The `show*` functions below are **your UI** — the SDK owns the logic, you own the screens.

> [tab] TypeScript
>
> ```typescript theme={"system"}
> import { getDefaultClient, updateUser } from '@dynamic-labs-sdk/client';
> import { isUserMissingMfaAuth } from '@dynamic-labs-sdk/client';
> import {
>   isDynamicWaasEnabled,
>   getChainsMissingWaasWalletAccounts,
>   createWaasWalletAccounts,
> } from '@dynamic-labs-sdk/client/waas';
>
> async function runSetup() {
>   const user = getDefaultClient().user;
>   if (!user) return;
>
>   // Required fields
>   if (user.missingFields?.length) {
>     const values = await showFieldForm(user.missingFields);
>     await updateUser({ userFields: values });
>   }
>
>   // MFA enrollment
>   if (isUserMissingMfaAuth()) {
>     await showMfaEnrollment();
>   }
>
>   // Embedded wallet creation
>   const missingChains = getChainsMissingWaasWalletAccounts();
>   if (isDynamicWaasEnabled() && missingChains.length) {
>     await createWaasWalletAccounts({ chains: missingChains });
>   }
>
>   // The user is ready — render your app.
> }
> ```

> [tab] React
>
> ```tsx theme={"system"}
> import { useUser } from '@dynamic-labs-sdk/react-hooks';
> import { isUserMissingMfaAuth } from '@dynamic-labs-sdk/client';
> import {
>   isDynamicWaasEnabled,
>   getChainsMissingWaasWalletAccounts,
> } from '@dynamic-labs-sdk/client/waas';
>
> export function SetupGate({ children }: { children: React.ReactNode }) {
>   const { data: user } = useUser();
>   if (!user) return null;
>
>   if (user.missingFields?.length) return <FieldForm fields={user.missingFields} />;
>   if (isUserMissingMfaAuth()) return <MfaEnrollment />;
>   if (isDynamicWaasEnabled() && getChainsMissingWaasWalletAccounts().length) {
>     return <CreateWallet />;
>   }
>
>   return <>{children}</>;
> }
> ```

The complete implementation — every step's UI, recovery-code acknowledgment, device registration, and lazy wallet creation — is in [Post-login user setup](https://docs.dynamic.xyz/docs/javascript/building-ui/post-auth-user-setup.md).

## See also

* [Post-login user setup (Building UI)](https://docs.dynamic.xyz/docs/javascript/building-ui/post-auth-user-setup.md)
* [MFA](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/mfa.md)
* [Embedded wallets: setup & creation](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/embedded-wallets-setup.md)
* [Account conflict resolution](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/account-conflict-resolution.md)


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