There are three ways to implement authentication in your application, each offering different levels of customization and control:
AuthButton component from @coinbase/cdp-react: Pre-built UI component (fastest integration)
React hooks from @coinbase/cdp-hooks: For custom React UIs with state management
Direct methods from @coinbase/cdp-core: For vanilla JavaScript/TypeScript or non-React frameworks
Important authentication considerations:
Always check if a user is already signed in before starting a new authentication flow. Attempting to call verifyEmailOTP or ‘verifySMSOTP` while a user is already authenticated will result in an error and may leave the application in an inconsistent state.
To sign out users, use the signOut() method from @coinbase/cdp-core, the useSignOut() hook from @coinbase/cdp-hooks, or the AuthButton component which handles sign out automatically.
For the fastest integration, @coinbase/cdp-react provides a pre-built AuthButton component that handles the entire authentication flow with a single line of code.
For more CDP React components and styling options, see the React Components documentation.By default, email authentication is the only method enabled. For enabling additional methods, refer to the AppConfig documentation
For React applications, @coinbase/cdp-hooks provides convenient hooks that handle state management and re-renders automatically.
Report incorrect code
Copy
Ask AI
import { CDPHooksProvider } from "@coinbase/cdp-hooks";import { type Config } from "@coinbase/cdp-core";const config: Config = { projectId: "your-project-id", ethereum: { createOnLogin: "eoa", },};// Wrap your app with the providerfunction App() { return ( <CDPHooksProvider config={config}> <YourApp /> </CDPHooksProvider> );}
The React hooks automatically handle loading states, error states, and re-renders when authentication state changes. They’re the recommended approach for React applications.
The @coinbase/cdp-core package provides the low-level authentication primitives for maximum control over the user experience. This approach is ideal for non-React applications or when you need fine-grained control.
Report incorrect code
Copy
Ask AI
import { initialize, signInWithEmail, verifyEmailOTP } from '@coinbase/cdp-core';// Step 1: Initialize the CDP SDKawait initialize({ projectId: 'your-project-id'});// Step 2: Initiate email authenticationconst { flowId, message } = await signInWithEmail({ email: '[email protected]'});console.log(message); // "OTP sent to [email protected]"// Step 3: Verify the OTP codeconst { user, isNewUser } = await verifyEmailOTP({ flowId, otp: '123456'});// User is now authenticated and has access to their walletconsole.log('User ID:', user.userId);console.log('EVM Addresses:', user.evmAccounts);console.log('Is new user:', isNewUser);
Always handle authentication errors gracefully. Common errors include:
The SDK uses expo-web-browser to automatically handle the OAuth redirect and callback. You don’t need to add Linking.addEventListener or other deep link handling code.
Some developers take additional action (fetching additional data, starting asynchronous processes) based on a user having an active session. For security reasons, it is important that you check authentication status by validating the access token Coinbase grants a user when they log in.
Report incorrect code
Copy
Ask AI
import { useGetAccessToken, useIsSignedIn } from "@coinbase/cdp-hooks";import { useEffect, useState } from "react";export default function useServerSideAuth() { const { isSignedIn } = useIsSignedIn(); const { getAccessToken } = useGetAccessToken(); const [isServerSideAuthenticated, setIsServerSideAuthenticated] = useState<boolean>(false); // When the user signs in, we need to check if the user is authenticated on the server side. useEffect(() => { async function checkAuth() { if (!isSignedIn) { return; } // Retrieve the access token const accessToken = await getAccessToken(); // Send the access token to your server to check if the user is authenticated. const response = await fetch("/api/check-auth", { method: "POST", body: JSON.stringify({ accessToken, }), }); const { isAuthenticated, endUser, error } = await response.json(); if (isAuthenticated) { setIsServerSideAuthenticated(true); console.log("endUser", endUser); } else { setIsServerSideAuthenticated(false); console.log("error", error); } } void checkAuth(); }, [isSignedIn, getAccessToken]); return isServerSideAuthenticated;}