Skip to main content

Overview

The VerifyMfa component provides a solution for prompting users to verify their identity using multi-factor authentication. It is designed for users who have already enrolled in MFA and need to enter their authenticator code to complete a sensitive action. The core features include:
  • TOTP (Time-based One-Time Password) verification via authenticator apps
  • Clean, focused verification interface
  • Composable UI that gives developers full control over layout and styling
  • Success and error callbacks for handling verification results
  • Centralized state management for the verification process

Architecture

The component is built using a composition pattern that allows for maximum flexibility while providing sensible defaults when customization is not needed.

Composition model

The VerifyMfa component is composed of several subcomponents that work together to create the verification experience. This approach allows developers to customize the UI structure while maintaining the underlying functionality. The main components are:
  • VerifyMfa: The root wrapper component that provides the VerifyMfaContext and manages state
  • VerifyMfaTitle: Renders the title for the verification interface
  • VerifyMfaDescription: Renders the description/instructions
  • VerifyMfaImage: Renders the verification icon/image
  • VerifyMfaFlow: Renders the verification form with OTP input
  • VerifyMfaFooter: The “Secured by Coinbase” footer

VerifyMfa

The VerifyMfa component accepts a children prop that can be either React nodes or a render function. When using a render function, it receives the current VerifyMfaState as an argument, providing access to all state values without needing to use the useVerifyMfaContext hook directly. Example of children as a render function:
function MyVerifyMfaPage() {
  return (
    <VerifyMfa onSuccess={(code) => console.log('Verified with code:', code)}>
      {(state) => (
        <>
          <VerifyMfaTitle />
          <VerifyMfaDescription />
          <VerifyMfaFlow />
          {state.error && <p className="error">{state.error}</p>}
          {state.isSuccess && <p className="success">Verified!</p>}
        </>
      )}
    </VerifyMfa>
  );
}

State management (VerifyMfaProvider and VerifyMfaContext)

The entire verification flow’s state is managed by VerifyMfaProvider and accessed via the useVerifyMfaContext hook. This context contains:
  • method: The currently selected MFA method (currently only “totp”)
  • methods: Array of available MFA methods for verification
  • step: The current step (currently only “verification”)
  • mfaCode: The verification code entered by the user
  • error: Any error that occurred during verification
  • isPending: Whether a verification request is in progress
  • isSuccess: Whether the verification was successful

VerifyMfaFlow

The VerifyMfaFlow component renders the OTP input form. It handles user input, form submission, and displays loading/success states.

Example: Basic usage

Implement a simple MFA verification prompt:
import { VerifyMfa } from '@coinbase/cdp-react';

function VerifyIdentity() {
  const handleSuccess = (mfaCode: string) => {
    console.log('Verified successfully!');
    // Proceed with the sensitive action
  };

  const handleError = (error: Error) => {
    console.error('Verification failed:', error);
  };

  return (
    <VerifyMfa 
      onSuccess={handleSuccess}
      onError={handleError}
    />
  );
}

Example: Custom layout

Customize the verification interface:
import {
  VerifyMfa,
  VerifyMfaDescription,
  VerifyMfaFlow,
  VerifyMfaImage,
  VerifyMfaTitle,
  useVerifyMfaContext,
} from '@coinbase/cdp-react';

function CustomVerifyMfa() {
  return (
    <VerifyMfa onSuccess={(code) => console.log('Verified!')}>
      <CustomVerifyContent />
    </VerifyMfa>
  );
}

function CustomVerifyContent() {
  const { state } = useVerifyMfaContext();

  return (
    <div className="custom-verify-container">
      <div className="verify-header">
        <VerifyMfaImage />
        <VerifyMfaTitle />
        <VerifyMfaDescription />
      </div>

      <VerifyMfaFlow className="verify-form" />

      {state.isPending && (
        <p className="status">Verifying...</p>
      )}

      {state.error && (
        <div className="error-message">
          {typeof state.error === 'string' ? state.error : state.error.message}
        </div>
      )}

      <p className="help-text">
        Open your authenticator app to get the 6-digit code.
      </p>
    </div>
  );
}

Example: Accessing state with render function

Use the render function pattern for state access:
import {
  VerifyMfa,
  VerifyMfaFlow,
  VerifyMfaTitle,
  VerifyMfaDescription,
} from '@coinbase/cdp-react';

function App() {
  return (
    <VerifyMfa 
      onSuccess={handleSuccess}
      onError={handleError}
    >
      {(state) => (
        <>
          <h2>Enter your code</h2>
          <VerifyMfaFlow />
          
          {state.isPending && <span>Verifying...</span>}
          {state.isSuccess && <span className="success">Verified!</span>}
          {state.error && (
            <span className="error">
              {typeof state.error === 'string' ? state.error : state.error.message}
            </span>
          )}
        </>
      )}
    </VerifyMfa>
  );
}

API Reference

Optional Props

  • onSuccess: Callback function invoked when verification is successful. Receives the MFA code as an argument.
  • onError: Callback function invoked when verification fails. Receives the error object.
  • children: React nodes for custom layout, or a function that receives VerifyMfaState
  • className: Additional CSS classes to apply to the root element

Notes

  • For enrolled users only: This component is designed for users who have already completed MFA enrollment. Use EnrollMfa for the enrollment flow.
  • Currently supports TOTP only: The component is designed to support multiple MFA methods, but currently only TOTP (authenticator app) verification is available.
  • Automatic form submission: The verification form automatically submits when the user enters a complete 6-digit code.