Skip to main content

Overview

Multi-Factor Authentication (MFA) adds an extra layer of security to Embedded Wallets by requiring users to verify their identity through a secondary authentication method.

TOTP

Time-based codes from authenticator apps like Google Authenticator, Authy, or 1Password

SMS

Verification codes sent via text message to the user’s phone
MFA is optional but strongly recommended for production applications handling significant value or sensitive operations. It provides defense against account takeover attacks even if the primary authentication method is compromised.
These guides will walk you through how to integrate Coinbase Developer Platform’s MFA into your application. For more detailed customization options, see the SDK reference.

How it works

1

Enrollment

  • Authenticator app: User scans a QR code and registers the app in their authenticator app
  • Text message: User provides their phone number in E.164 format (e.g., +14155552671)
2

Verification

  • Authenticator app: User confirms by entering a 6-digit code
  • Text message: User confirms by entering a 6-digit code sent via SMS
3

Future authentication

  • Authenticator app: User provides a 6-digit code for sensitive operations
  • Text message: User receives a new 6-digit code via SMS for sensitive operations
Users must be authenticated (signed in) before they can enroll in MFA. Users can enroll in both TOTP and SMS for maximum flexibility.

MFA-protected operations

The following actions automatically trigger MFA verification when the user is enrolled:
  • signEvmHash
  • signEvmTypedData
  • signEvmMessage
  • signEvmTransaction
  • sendEvmTransaction
  • sendUserOperation
  • createEvmKeyExportIframe
  • signSolanaMessage
  • signSolanaTransaction
  • sendSolanaTransaction
  • createSolanaKeyExportIframe

Supported authenticator apps

Any TOTP-compatible authenticator app works. These are commonly used:

Quickstart

If you’re using @coinbase/cdp-react, use the pre-built enrollment component to let users enable MFA:
import { EnrollMfaModal } from "@coinbase/cdp-react";

function Settings() {
  return (
    <EnrollMfaModal onEnrollSuccess={() => console.log("MFA enabled!")}>
      <button>Enable Two-Factor Authentication</button>
    </EnrollMfaModal>
  );
}
Once enrolled in MFA, users see a verification modal whenever they attempt a protected operation:
import { CDPReactProvider } from "@coinbase/cdp-react";
import { useSendEvmTransaction } from "@coinbase/cdp-hooks";

function App() {
  return (
    <CDPReactProvider config={{ projectId: "your-project-id" }}>
      <SendButton />
    </CDPReactProvider>
  );
}

function SendButton() {
  const { sendEvmTransaction, isPending } = useSendEvmTransaction();

  const handleSend = async () => {
    // If user is enrolled in MFA, modal appears automatically
    const hash = await sendEvmTransaction({
      to: "0x...",
      value: "1000000000000000000",
    });
  };

  return <button onClick={handleSend} disabled={isPending}>Send</button>;
}
That’s it! The SDK handles:
  1. Detecting when MFA verification is needed
  2. Showing the verification modal
  3. Completing the operation after successful verification