CDP Frontend SDK
    Preparing search index...

    Module @coinbase/cdp-hooks - v0.0.20

    This package provides React hooks for conveniently accessing embedded wallet functionality. Built on top of @coinbase/cdp-core, it offers a React-friendly interface for end user authentication and embedded wallet operations.

    This guide will help you get started with @coinbase/cdp-hooks. You'll learn how to install the package, set up the provider, and use the hooks in a variety of ways.

    First, add the package to your project using your preferred package manager.

    # With npm
    npm install @coinbase/cdp-core @coinbase/cdp-hooks

    # With pnpm
    pnpm add @coinbase/cdp-core @coinbase/cdp-hooks

    # With yarn
    yarn add @coinbase/cdp-core @coinbase/cdp-hooks
    1. Sign in or create an account on the CDP Portal
    2. On your dashboard, select a project from the dropdown at the at the top, and copy the Project ID
    1. Navigate to the Embedded Wallet Configuration in CDP Portal, and click Add origin to include your local app
    2. Enter the origin of your locally running app - e.g., http://localhost:3000
    3. Click Add origin again to save your changes

    Next, you need to wrap your application with the CDPHooksProvider, which provides the necessary context for hooks to work correctly.

    Update your main application file (e.g., main.tsx) to include the provider:

    import { CDPHooksProvider } from "@coinbase/cdp-hooks";
    import { App } from './App'; // Your main App component

    function App() {
    return (
    <CDPHooksProvider
    config={{
    // Copy and paste your project ID here.
    projectId: "your-project-id",
    }}
    >
    <App />
    </CDPHooksProvider>
    );
    }

    End user authentication proceeds in two steps:

    1. The user inputs their email address to initiate the authentication flow, which will send the user a One Time Password (OTP) and return a flowId
    2. The user submits the six-digit OTP and flowId, after which the user will be authenticated, returning a User object.

    The following code demonstrates this flow:

    import { useSignInWithEmail, useVerifyEmailOTP } from "@coinbase/cdp-hooks";

    function SignIn() {
    const { signInWithEmail } = useSignInWithEmail();
    const { verifyEmailOTP } = useVerifyEmailOTP();

    const handleSignIn = async (email: string) => {
    try {
    // Start sign in flow
    const { flowId } = await signInWithEmail({ email });

    // In a real application, you would prompt the user for the OTP they received
    // in their email. Here, we hardcode it for convenience.
    const otp = "123456";

    // Complete sign in
    const { user, isNewUser } = await verifyEmailOTP({
    flowId,
    otp
    });

    console.log("Signed in user:", user);
    console.log("User EVM address", user.evmAccounts[0]);
    } catch (error) {
    console.error("Sign in failed:", error);
    }
    };

    return <button onClick={() => handleSignIn("user@example.com")}>Sign In</button>;
    }

    Once the end user has signed in, you can display their information in your application:

    import { useCurrentUser, useEvmAddress } from "@coinbase/cdp-hooks";

    function UserInformation() {
    const { currentUser: user } = useCurrentUser();
    const { evmAddress } = useEvmAddress();

    if (!user) {
    return <div>Please sign in</div>;
    }

    const emailAddress = user.authenticationMethods.email?.email;

    return (
    <div>
    <h2>User Information</h2>
    <p>User ID: {user.userId}</p>
    <p>EVM Address: {evmAddress}</p>
    { email && <p>EmailAddress: {emailAddress}</p>}
    </div>
    );
    }

    We support signing and sending a Blockchain transaction in a single action on the following networks:

    • Base
    • Base Sepolia
    • Ethereum
    • Ethereum Sepolia
    • Avalanche
    • Arbitrum
    • Optimism
    • Polygon
    import { useSendEvmTransaction, useEvmAddress } from "@coinbase/cdp-hooks";

    function SendTransaction() {
    const { sendEvmTransaction: sendTransaction } = useSendEvmTransaction();
    const { evmAddress } = useEvmAddress();

    const handleSend = async () => {
    if (!evmAddress) return;

    try {
    const result = await sendTransaction({
    evmAccount: evmAddress,
    transaction: {
    to: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    value: 100000000000000n, // 0.0001 ETH in wei
    nonce: 0,
    gas: 21000n,
    maxFeePerGas: 30000000000n,
    maxPriorityFeePerGas: 1000000000n,
    chainId: 84532, // Base Sepolia
    type: "eip1559",
    }
    });

    console.log("Transaction hash:", result.transactionHash);
    } catch (error) {
    console.error("Transaction failed:", error);
    }
    };

    return <button onClick={handleSend}>Send Transaction</button>;
    }

    For networks other than those supported by the CDP APIs, your end user must sign the transaction, and then you must broadcast the transaction yourself. This example uses the public client from viem to broadcast the transaction.

    import { useSignEvmTransaction, useEvmAddress } from "@coinbase/cdp-hooks";
    import { http, createPublicClient } from "viem";
    import { tron } from "viem/chains";

    function CrossChainTransaction() {
    const { signEvmTransaction: signTransaction } = useSignEvmTransaction();
    const { evmAddress } = useEvmAddress();

    const handleSend = async () => {
    if (!evmAddress) return;

    try {
    // Sign the transaction
    const { signedTransaction } = await signTransaction({
    evmAccount: evmAddress,
    transaction: {
    to: "0x...",
    value: 100000000000000n,
    nonce: 0,
    gas: 21000n,
    maxFeePerGas: 30000000000n,
    maxPriorityFeePerGas: 1000000000n,
    chainId: 728126428, // Tron
    type: "eip1559",
    }
    });

    // Broadcast using a different client
    const client = createPublicClient({
    chain: tron,
    transport: http()
    });

    const hash = await client.sendRawTransaction({
    serializedTransaction: signedTransaction
    });

    console.log("Transaction hash:", hash);
    } catch (error) {
    console.error("Transaction failed:", error);
    }
    };

    return <button onClick={handleSend}>Send Transaction</button>;
    }

    End users can sign EVM messages, hashes, and typed data to generate signatures for various onchain applications.

    import { useSignEvmMessage, useSignEvmTypedData, useEvmAddress } from "@coinbase/cdp-hooks";

    function SignData() {
    const { signEvmMessage: signMessage } = useSignEvmMessage();
    const { signEvmTypedData: signTypedData } = useSignEvmTypedData();
    const { signEvmHash: signHash } = useSignEvmHash();
    const { evmAddress } = useEvmAddress();

    const handleSignHash = async () => {
    if (!evmAddress) return;

    const result = await signMessage({
    evmAccount: evmAddress,
    message: "Hello World"
    });

    console.log("Message signature:", result.signature);
    }

    const handleSignMessage = async () => {
    if (!evmAddress) return;

    const result = await signMessage({
    evmAccount: evmAddress,
    message: "Hello World"
    });

    console.log("Message signature:", result.signature);
    };

    const handleSignTypedData = async () => {
    if (!evmAddress) return;

    const result = await signTypedData({
    evmAccount: evmAddress,
    typedData: {
    domain: {
    name: "Example DApp",
    version: "1",
    chainId: 84532,
    },
    types: {
    Person: [
    { name: "name", type: "string" },
    { name: "wallet", type: "address" }
    ]
    },
    primaryType: "Person",
    message: {
    name: "Bob",
    wallet: evmAddress
    }
    }
    });

    console.log("Typed data signature:", result.signature);
    };

    return (
    <div>
    <button onClick={handleSignMessage}>Sign Message</button>
    <button onClick={handleSignTypedData}>Sign Typed Data</button>
    <button onClick={handleSignHash}>Sign Hash</button>
    </div>
    );
    }

    End users can export their private keys from their embedded wallet, allowing them to import it into an EVM-compatible wallet of their choice.

    import { useExportEvmAccount, useEvmAddress } from "@coinbase/cdp-hooks";

    function ExportKey() {
    const { exportEvmAccount: exportAccount } = useExportEvmAccount();
    const { evmAddress } = useEvmAddress();

    const handleExport = async () => {
    if (!evmAddress) return;

    try {
    const { privateKey } = await exportAccount({
    evmAccount: evmAddress
    });

    console.log("Private Key:", privateKey);
    // Warning: Handle private keys with extreme care!
    } catch (error) {
    console.error("Export failed:", error);
    }
    };

    return <button onClick={handleExport}>Export Private Key</button>;
    }

    Functions

    useConfig
    useIsInitialized
    useSignInWithEmail
    useSignInWithSms
    useVerifyEmailOTP
    useVerifySmsOTP
    useIsSignedIn
    useCurrentUser
    useSignOut
    useGetAccessToken
    useEvmAddress
    useSignEvmHash
    useSignEvmTransaction
    useSendEvmTransaction
    useSignEvmMessage
    useSignEvmTypedData
    useExportEvmAccount
    useEnforceAuthenticated
    useEnforceUnauthenticated
    CDPHooksProvider

    Classes

    APIError

    Interfaces

    CDPHooksProviderProps
    CDPContextValue
    EIP712TypedData

    Type Aliases

    Config
    TransactionState
    AllowedEvmTransactionType
    APIErrorType
    EvmAddress
    ExportEvmAccountOptions
    ExportEvmAccountResult
    Hex
    SendEvmTransactionOptions
    SendEvmTransactionResult
    SignEvmHashOptions
    SignEvmHashResult
    SignEvmMessageOptions
    SignEvmMessageResult
    SignEvmTransactionOptions
    SignEvmTransactionResult
    SignEvmTypedDataOptions
    SignEvmTypedDataResult
    SignInWithEmailOptions
    SignInWithEmailResult
    User
    VerifyEmailOTPOptions
    VerifyEmailOTPResult

    Variables

    CDPContext