Overview
Build a complete React demo app from scratch to learn embedded wallets! This tutorial usescdp-create-app
to create a working app, then explains the key concepts and code.
Prerequisites
- A free CDP Portal account and project
- Node.js 22+
- A node package manager installed (i.e.,
npm
,pnpm
, oryarn
) - Basic familiarity with React and TypeScript
Configured your domain in CDP Portal (click to expand)
1Access CDP Portal
Navigate to the Domains Configuration in CDP Portal, and click Add domain to include your local app.2Add your domain
- For local development: Use
http://localhost:3000
(or your preferred port) - For production: Use your actual domain (e.g.,
https://yourapp.com
)
For production apps, only add your actual production domain. Do not addlocalhost
to production CDP projects as malicious apps running locally could impersonate your frontend and abuse your project credentials.3Save your changes
Click Add domain again to save your changes.You should see your domain listed in the CDP Portal dashboard. The allowlist will take effect immediately upon saving.- For local development: Use
Create the demo app
1
Copy your Project ID
Navigate to CDP Portal and select your project from the top-left dropdown. Clicking the gear icon will take you to your project details:
Copy the Project ID value. You will use this in the next step when configuring your demo app.

2
Create a new demo app
Use the latest version of
create-cdp-app
to create a new demo app. Replace <your-project-id>
with your actual project ID from the previous step:3
Confirm domain whitelist
You will be prompted to confirm the localhost domain (which you should have already configured in the setup above):
4
Run your app
Navigate to your project directory, install dependencies, and start the development server:
Demo your new wallet
Now that your embedded wallet is configured and your app is running, let’s try it out.1
Sign in
Head to http://localhost:3000 and click the Sign In button.

2
Enter your email

3
Verify
Enter the verification code sent to your e-mail.

4
View your new wallet
Congrats! Your new embedded wallet has been created, authenticated, and is ready to use on the Base Sepolia network.From the demo app, you can copy-and-paste your wallet address from the top-right corner. You can also monitor your wallet balance and (eventually — keep reading!) send transactions. You should see similar to the following:
Find record of your new wallet on Base Sepolia explorer using the URL:

https://sepolia.basescan.org/address/YOUR-WALLET-ADDRESS
.5
Fund your wallet with testnet ETH
Before you can send transactions, you’ll need to fund your wallet with testnet ETH. Follow the link to request testnet funds from a Base Faucet.

6
Send your first transaction
Now that your wallet has testnet ETH, you can send your first transaction! The demo app allows you to send 0.000001 ETH to yourself as a test.Click Send Transaction to initiate the transfer. Once complete, you’ll see a transaction hash that you can look up on the blockchain explorer.
🎉 You’ve successfully created an embedded wallet and sent your first transaction! Try adding some React Hooks or additional components to expand your app.

How it works
Want to customize your app or understand how CDP makes wallets so simple? Let’s look at the key components that power your new embedded wallet.File structure
The demo app is built with React and Vite, organized into these main files:You can explore the package for this demo in more detail at npmjs.com.
Entry point + provider setup
src/main.tsx
demonstrates how to wrap your app with the CDPReactProvider
to enable CDP functionality throughout the component tree.
src/main.tsx
CDP_CONFIG
contains your Project ID from setup, stored securely in an environment variable (VITE_CDP_PROJECT_ID
).
By default the app creates an EVM EOA account for the user on sign in. To create a Smart Account, set createAccountOnLogin
to evm-smart
in the config.
The APP_CONFIG
contains metadata about your application:
- name: Your app’s display name shown in the wallet UI
- logoUrl: URL to your app’s logo displayed during authentication
Auth state management
src/App.tsx
demonstrates how CDP simplifies wallet state management with two simple hooks:
src/App.tsx
useIsInitialized()
: Know when the SDK is ready (no manual provider checks!)useIsSignedIn()
: Instant auth status (no complex wallet connection state)
Sign-in interface
src/SignInScreen.tsx
showcases how to provide the Sign in experience to your users.
src/SignInScreen.tsx
AuthButton
component handles:
- Email authentication: No seed phrases to manage - users maintain full control
- Wallet creation: Automatically creates a self-custodial wallet on first sign-in
- Session management: Handles tokens and persistence
- UI/UX: Professional auth flow with email verification
The authenticated experience
src/SignedInScreen.tsx
shows how to manage the authenticated session of a user.
Two important hooks to highlight here:
useEvmAddress()
: Fetch the user’s wallet addressuseIsSignedIn()
: Returns true if the user is signed in
src/SignedInScreen.tsx
src/SignedInScreen.tsx
Sending transactions
src/Transaction.tsx
demonstrates how to send ETH using CDP’s transaction hooks.
Key CDP hooks to highlight here:
useSendEvmTransaction()
: Sends transactions from the user’s addressuseEvmAddress()
: Gets the current user’s address
sendEvmTransaction
:
src/Transaction.tsx
src/Transaction.tsx
- Loading skeletons while fetching balance
- Empty wallet state with faucet link
- Ready state with send button
- Success state with transaction hash and option to send another
Wallet management header
src/Header.tsx
provides a clean interface for users to view their wallet address and manage their session.
src/Header.tsx
- Wallet display: Shows truncated address (e.g.,
0x1234...5678
) - Copy to clipboard: One-click copying with visual feedback
- Session management: Sign out via CDP’s
AuthButton
Balance display
src/UserBalance.tsx
displays the user’s ETH balance with a helpful faucet link.
src/UserBalance.tsx
- Shows ETH balance with an icon
- Loading skeleton while fetching balance
- Direct link to the faucet for getting testnet funds
Theme customization
The demo app provides extensive theming capabilities through CSS variables and the CDP theme system, allowing you to fully customize the look and feel to match your brand.src/theme.ts
- Dark mode support: Enables light and dark themes
- Customizable colors: Primary accent, backgrounds, text, borders, and more
- Typography control: Font family and base font size
- Responsive breakpoints: Different styles for mobile, tablet, and desktop
- Component theming: Style CDP components like buttons, inputs, and modals
index.css
, making it easy to rebrand the entire app by updating a few color values.
For more information on theme customization, see the theme customization documentation.
What to read next
Quickstart
Quick integration guide for existing React apps
React Hooks
Learn about available hooks like useSignInWithEmail, useEvmAddress, and useSendEvmTransaction
React Components
Explore pre-built components for authentication, wallet management, and transactions
Next.js Integration
Build with Next.js using “use client” requirements