[Optional] Set Up Authentication

Crossmint wallets work with your existing authentication or directly with preferred auth partners.

If you're creating wallets for your users, you will need a way to securely authenticate a given user so that they (and only them) can have access to their resources. In this guide, we explain how you can connect Crossmint wallet APIs to an existing auth solution, or build one from scratch in minutes by using pre-made sample code with leading auth providers such as Stytch, Firebase, Auth0 or Dynamic.xyz.

Getting Started with Stytch

For this authentication method we’ve built an open source repository to get started with Crossmint’s Stytch style integration.

In this guide you will learn how to:

  • Set up Stytch authentication in your app.
  • Create Crossmint wallets attached to Stytch users on any supported chain.

Repository Setup:

  1. Download the stytch-crossmint repository
  2. Open the project in your favorite IDE.
  3. In the root directory of the project, rename the file called .env.template to .env.local. You'll be filling out this file throughout the setup process.

Stytch Setup:

  1. Create a Stytch account.
    a. When prompted between “Consumer Authentication” and “B2B Authentication, select the “Consumer Authentication” option.
  2. Navigate to Frontend SDKs on the side-bar.

a. Select Test environment (should be the default option).
b. Click the Enable SDK button and confirm the prompt. This will create your Stytch API keys.

  1. Add an authorized environment:
    a. Click on the “+ Add” button
    b. Add your site/vercel or local domain to be authorized.

c. Click "Save".

  1. Adding your API Keys to the project.
    a. Go to API Keys in the Configuration section
    b. Select the Test environment and copy the Public Token located at the bottom of the page.

Should look like this:

c. In the crossmint-stytch project, paste the copied value for the variables:


into the .env.local file

Example: NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN=public-token-test-xxxxx…

Crossmint Setup:

Now you need to sign up in Crossmint and create an API key that allows you to create and manage wallets for your users. During development, you’re going to create wallets in Crossmint’s staging sandbox.

  1. Go to staging.crossmint.com/console and sign in / create an account.

  2. Go to API keys and create a New API Key with scope for wallets.read and wallets.create.

Finally save your new key and copy the CLIENT SECRET and Project ID values for later.

  1. In the crossmint-stytch project, set the value of the following three keys in the .env.local file:



Once entered, save the file.



Crossmint wallet APIs are server-side ONLY. Make sure your client secret doesn't get leaked, as it would allow others to create wallets and manage assets for your users.

Running the Project Locally

Run the following command to get the project up and running:
yarn dev

You can view your locally hosted site on http://localhost:3000


Getting Started with Auth0

Auth0 is a much more seamless integration without having the worry of having any additional api routes on your server.

Setting up Auth0:

To get started, authenticate with Auth0 and on the Getting Started page, click on "Create Application"

In this example, we'll be using a Single Page Web Application

Once selected, click on "Create" and you'll be navigated to your application page. On this page, select "Settings"

Inside of the settings page, you can see all of your API keys that you'll need to use under "Basic Information".

Here are the values you'll need:

  • Domain
  • Client ID
  • Client Secret

Adding Crossmint Action

On the left-side tab, go to Actions->Flows

Under flows, select Login

Add an action by browsing the marketplace

Select the Crossmint Action

Click on Add Integration

Follow the remaining steps presented on screen.

Getting started with NextAuth

NextAuth allows you to be in full control of authentication, letting you select which auth providers you'd like to use, control over jwt storage and more!

To get started, begin by following this guide from NextAuth to configure your repo to use NextAuth. Once you've got that setup, we can move on to the integration steps.

Configuring NextAuth with Crossmint

In order to use Crossmint wallets with NextAuth, we need to enable some callbacks so that we can create and fetch wallets for a user after they've managed to successfully authenticate.

In your [...nextauth].js file, we want to ensure jwt is enabled in our session and add 3 callbacks (signIn, jwt, and session).

Here's some sample code of our [...nextauth].js file using Google OAuth:

import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import { WalletService } from "@/services/wallets";

export const authOptions = {
    providers: [
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET
    session: {
        jwt: true,
    callbacks: {
        async signIn({ user, isNewUser }) {
            if (isNewUser) {
                console.info(`NextAuth: created user ${user.id}`);
                await WalletService.createWallets(user.id);
                console.info(`NextAuth: initialized wallet for user ${user.id}`);

            console.info(`NextAuth: fetching wallets for user ${user.id}`);
            user.wallets = await WalletService.fetchWallets(user.id);
            return true;
        async jwt({ token, user, account, profile, isNewUser }) {
            if (user) {
                token.wallets = user.wallets;
            return token;
        async session({ session, token }) {
            session.wallets = token.wallets;
            return session;

export default NextAuth(authOptions);

We'll also need to add the wallets service which will be used for creating/fetching the wallets:
Here's our service file which just uses 2 api endpoints (Creating a wallet and Fetching your wallets)

export class WalletService {
    static async fetchWallets(userId) {
        let walletsMap = {};
        const existingWallets = await WalletService.#fetchWalletsInternal(userId);
        existingWallets.forEach((wallet) => {
            const chain = wallet.chain;
            const address = wallet.publicKey;
            walletsMap[chain] = address;

        return walletsMap;

    static async createWallets(userId) {
        const url = `${process.env.CROSSMINT_BASEURL}/api/v1-alpha1/wallets`;
        const options = WalletService.#createOptions(
            "POST", { chain: "ethereum", userId: userId });
        return WalletService.#fetchWithExceptionHandling(url, options);

    static async #fetchWalletsInternal(userId) {
        const url = new URL(`${process.env.CROSSMINT_BASEURL}/api/v1-alpha1/wallets`);
        url.searchParams.append('userId', userId);

        const options = WalletService.#createOptions("GET");

        return WalletService.#fetchWithExceptionHandling(url, options);

    static #createOptions(method, body = null) {
        return {
            method: method,
            headers: {
                accept: "application/json",
                "X-CLIENT-SECRET": process.env.CROSSMINT_X_CLIENT_SECRET,
                "X-PROJECT-ID": process.env.CROSSMINT_X_PROJECT_ID,
                ...(body && { "content-type": "application/json" })
            ...(body && { body: JSON.stringify(body) })

    static async #fetchWithExceptionHandling(url, options) {
        try {
            const response = await fetch(url, options);
            return await response.json();
        } catch (error) {
            console.error("Error whilst fetching", error);
            throw new Error("An internal error has occurred");

With this, you're done and now can start using the wallet values!

Using Wallets from NextAuth:

Here's how you would get the wallets once a user has successfully authenticated on your platform:

    const { data: session } = useSession();
    if (!session) {

    const { wallets } = session;