Skip to main content
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.
Step-up is scope-based, not MFA. You gate an action on a TokenScope 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.

What maps to what

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

Last modified on July 25, 2026