In this quickstart you will create a Next.js web app with smart wallets embedded. At the end of the tutorial, you will have learned how to:

  • Use Crossmint to log users into your app
  • Create a smart wallet (in an EVM testnet) for your users when they sign up
  • Set up a passkey (e.g. touch id / face id) to control the wallet
  • Retrieve the wallet address

Integration Steps

1. Create and Configure a Crossmint Project

To get started, create a developer account in the Crossmint Staging Console. Open that link, sign in, and accept the dialog to continue.

Crossmint offers two consoles: staging, for development and testing, and www, for production.

Then, navigate to project Settings > General, and change the wallet type to Smart Wallets.

Configure Project for Smart Wallets

2. Get an API Key

Navigate to the "Integrate" section on the left navigation bar, and ensure you're on the "API Keys" tab.

Within the Client-side keys section, click the "Create new key" button in the top right.

On the authorized origins section, enter http://localhost:3000 and click "Add origin".

Next, check the scopes labeled wallets.create, wallets.read, users.create.

Check the "JWT Auth" box

Finally, create your key and save it for subsequent steps.

3. Project Set Up

1

Create a new Next.js application

Use the create-next-app package to get started:

npx create-next-app@latest

If you see this message enter y and Enter to proceed:

Need to install the following packages:
  create-next-app@latest
Ok to proceed? (y)
2

Name your app `my-first-smart-wallet-app` and accept the default options

What is your project named? my-first-smart-wallet-app
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like to use `src/` directory? No
Would you like to use App Router? (recommended) Yes
Would you like to customize the default import alias? No
3

Change into the directory created in previous steps

cd my-first-smart-wallet-app
4

Install the Crossmint React SDK

pnpm add @crossmint/client-sdk-react-ui
5

Add a new file named `.env.local` to root directory of your project

Set your environment variables by adding your client-side API secret from Step 1.

These values are safe to use in the client side of your application and are not considered sensitive.
.env.local
NEXT_PUBLIC_CROSSMINT_API_KEY="_YOUR_API_KEY_"
6

Prepare wallet page

Open app/page.tsx, delete the contents, and leave a minimal page, for next steps.

page.tsx
"use client"; // Important: this ensures the wallet SDK only runs on the client

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <div className="absolute top-0 right-0 p-4">
        // TO-DO: we will add auth UI here
      </div>
      <div className="flex items-center justify-center w-full h-full">
        // TO-DO: we will add wallet UI here
      </div>
    </main>
  );
}

4. Set Up User Auth

Before creating wallets for your users, you need to implement a login system. In this quickstart, we’ll demonstrate this using Crossmint Auth, a fully managed authentication service provided by Crossmint. However, you can use any authentication system of your choice.

1

Configure Crossmint Auth in Layout

To configure auth, we need to create a new file for our Crossmint providers and then import it into our root layout.

Create a new file app/providers/Providers.tsx and add the following code:

app/providers/Providers.tsx
"use client";

import { CrossmintProvider, CrossmintAuthProvider } from "@crossmint/client-sdk-react-ui";

export default function Providers({ children }: { children: React.ReactNode }) {
  return (
    <CrossmintProvider apiKey={process.env.NEXT_PUBLIC_CROSSMINT_API_KEY ?? ""}>
      <CrossmintAuthProvider 
        embeddedWallets={{
          type: "evm-smart-wallet",
          defaultChain: "polygon-amoy",
          createOnLogin: "all-users"
        }}
      >
        {children}
      </CrossmintAuthProvider>
    </CrossmintProvider>
  );
}

Now, open app/layout.tsx and update it to use the new Providers component:

layout.tsx
// Add this import near the top
import Providers from "./providers/Providers";

// ...

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={/** ... **/}>
        {*/ And add this component inside the body, surrounding the children: */}
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  );
}

This setup encapsulates the Crossmint providers in a separate file, making your code more modular. The Providers component wraps your application with both CrossmintProvider and CrossmintAuthProvider, configuring the Crossmint SDK and auth. Note that we’re setting wallets to operate by default in the polygon-amoy testnet.

2

Add login and logout functionality

Now, add the following import to the top of your page.tsx file, below the "use client"; directive:

page.tsx
"use client";

// Add this
import { useAuth } from "@crossmint/client-sdk-react-ui";

Next, declare a component that handles the login and logout functionality. This component uses the useAuth hook to manage authentication state and provides buttons for logging in and out.

page.tsx
function AuthButton() {
  const { login, logout, jwt } = useAuth();

  return (
    <div>
      {jwt == null ? (
        <button 
          type="button" 
          onClick={login} 
          className="bg-blue-500 text-white font-bold py-2 px-4 rounded"
        >
          Login
        </button>
      ) : (
        <button 
          type="button" 
          onClick={logout} 
          className="bg-black text-white font-bold py-2 px-4 rounded border-2 border-blue-500"
        >
          Logout
        </button>
      )}
    </div>
  );
}

Finally, add the AuthButton component inside your Home component.

page.tsx
export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <div className="absolute top-0 right-0 p-4">
        {/** Added here */}
        <AuthButton />
      </div>
      <div className="flex items-center justify-center w-full h-full">
        // TO-DO: we will add wallet UI here
      </div>
    </main>
  );
}

5. Create and Use the Wallet

Finally, we are ready to create our first user smart wallet, which will use passkeys as a signer.

1

Display wallet address

Now, let’s display the wallet address in our UI. We will use the useWallet hook from the @crossmint/client-sdk-react-ui package to fetch the wallet details.

First, import the useWallet hook in your page.tsx file:

page.tsx
import { useAuth, useWallet } from "@crossmint/client-sdk-react-ui";

Next, declare a Wallet component that will use this hook to display the wallet address:

page.tsx
function Wallet() {
  const { wallet, status, error } = useWallet();

  return (
    <div>
      {status === "loading-error" && error && (
        <div className="border-2 border-red-500 text-red-500 font-bold py-4 px-8 rounded-lg">
          Error: {error.message}
        </div>
      )}
      {status === "in-progress" && (
        <div className="border-2 border-yellow-500 text-yellow-500 font-bold py-4 px-8 rounded-lg">
          Loading...
        </div>
      )}
      {status === "loaded" && wallet && (
        <div className="border-2 border-green-500 text-green-500 font-bold py-4 px-8 rounded-lg">
          Wallet: {wallet.address}
        </div>
      )}
      {status === "not-loaded" && (
        <div className="border-2 border-gray-500 text-gray-500 font-bold py-4 px-8 rounded-lg">
          Wallet not loaded
        </div>
      )}
    </div>
  );
}

Finally, add the Wallet component to your Home component, replacing the TO-DO placeholder:

page.tsx
export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <div className="absolute top-0 right-0 p-4">
        <AuthButton />
      </div>
      <div className="flex items-center justify-center w-full h-full">
        {/** Added here */}
        <Wallet />
      </div>
    </main>
  );
}

The Wallet component will display the wallet address if it’s loaded, show a loading message while the wallet is being fetched, and display an error message if there’s an error.

2

Run the React App and Log In

To see the authentication dialog and continue to see the results, follow these steps:

  1. From the root directory of your project, run the following command:
pnpm run dev
  1. The command line will output a localhost url and port, such as http://localhost:3000. Open it.

If the port is different than 3000, edit the API key from step 2 to add the right port and URL in the Crossmint console

  1. Click on the “Log In” button to open the authentication dialog.
  2. Follow the prompts to log in using your Passkey.
  3. Once logged in, you will see the wallet created and displayed using the Wallet component.

At the end of this process, you will be signed in with a wallet created using Passkeys!

Details on Signers

A signer is the account that will be used to control and manage the Account Abstraction wallet. Crossmint supports multiple options, including Passkeys, Privy, Dynamic, a Viem account or any EIP1193 compatible provider.

6. Next steps

And that’s it! You now have created an embedded Smart Wallet. Read more here on how to perform actions with your wallet with the SDK, like signing messages, transactions, and more.

Access gated

The Crossmint team must enable smart wallets in your project before you can use them. To get access, reach out using this form and specify your Project ID.

You can find the Project ID near the top right of the console overview page.