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

# Step-up authentication

> The React SDK could pop step-up UI inside the widget. In the JavaScript SDK you run the same scope-based check yourself and pass requestedScopes on the verify call.

In the React SDK, `useStepUpAuthentication()` could render the challenge for you: `promptStepUpAuth()` auto-picked a verification method, showed Dynamic's built-in UI, and stored the scoped **elevated access token**. The JavaScript SDK keeps the same scope-based model and the same `checkStepUpAuth()` check — but there's no built-in UI, so you collect the credential yourself and pass `requestedScopes` on the verify call.

> [!NOTE]
>
> Step-up is **scope-based, not MFA**. You gate an action on a [`TokenScope`](https://docs.dynamic.xyz/docs/javascript/building-ui/step-up-authentication#available-scopes) such as `wallet:sign`; any credential the user has — OTP, an authenticator app, a passkey, a recovery code, or a connected wallet — can satisfy it. MFA is just one such credential type. Migrating MFA enrollment itself is covered in [Multi-factor authentication](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/mfa.md).

## What maps to what

| React SDK (`useStepUpAuthentication`) | JavaScript SDK |
| - | - |
| `checkStepUpAuth({ scope })` | `checkStepUpAuth({ scope })` / `useCheckStepUpAuth()` (unchanged) |
| `isStepUpRequired({ scope })` | read `isRequired` from `checkStepUpAuth({ scope })` |
| `promptStepUpAuth()` / `promptMfa()` / `promptReauthenticate()` (Dynamic's UI) | No built-in UI — [build it](https://docs.dynamic.xyz/docs/javascript/building-ui/step-up-authentication.md), then call the verify function below with `requestedScopes` |
| `sendOtp()` / `verifyOtp()` | `sendEmailOTP()` / `sendSmsOTP()` + `verifyOTP({ …, requestedScopes })` |
| `verifyTotpMfa()` | `authenticateTotpMfaDevice({ deviceId, code, requestedScopes })` |
| `verifyPasskeyMfa()` | `authenticatePasskeyMFA({ requestedScopes })` |
| `verifyRecoveryCode()` | `authenticateMfaRecoveryCode({ code, requestedScopes })` |
| `verifyWallet()` | `verifyWalletAccount({ walletAccount, requestedScopes })` |
| `TokenScope` from `@dynamic-labs/sdk-api-core` | `TokenScope` from `@dynamic-labs-sdk/client` |

## Gating a sensitive action (what the widget did for you)

Where you used to call `promptStepUpAuth()` and let the widget render the challenge, the shape is now yours to run — but it's the same three beats in any JavaScript SDK app, so the full build (every credential type, the scopes table, the connected-wallet and external-JWT paths) lives in [**Step-up authentication** (Building UI)](https://docs.dynamic.xyz/docs/javascript/building-ui/step-up-authentication.md). The migration-specific parts:

* **Check the scope, not the UI.** Call `checkStepUpAuth({ scope })` right before the action and read `isRequired`. It defaults to `isRequired: true` if the check fails, so a network error never silently skips the challenge.
* **`requestedScopes` is what mints the elevated token.** Whatever verify call you run (`verifyOTP`, `authenticateTotpMfaDevice`, `verifyWalletAccount`, …), pass the scope in `requestedScopes`. Any credential the user has satisfies it — swap the verify call per the mapping table above.
* **The action takes no token.** After a successful verify, just perform the action — the SDK consumes the elevated token the verify call just minted; you don't thread a token through.

## See also

* [Step-up authentication](https://docs.dynamic.xyz/docs/javascript/building-ui/step-up-authentication.md) — the full build with every credential type, the scopes table, and the external-JWT path
* [Multi-factor authentication](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/mfa.md) — enroll the devices a challenge can use
* [Transactions & balance](https://docs.dynamic.xyz/docs/javascript/migrating-from-react/transactions-and-balance.md) — the signing action you gate


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