> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bring Your Own Auth

> Bring your own auth provider

<Note>
  **This page has been updated for Wallets SDK V1.** If you are using the previous version,
  see the [previous version of this page](/wallets/v0/guides/bring-your-own-auth) or the [V1 migration guide](/wallets/guides/migrate-to-v1).
</Note>

Crossmint provides connectors for the most popular auth providers, including Auth0, Firebase, Supabase, Stytch, Cognito, and Kinde.

When you bring your own auth, Crossmint automatically extracts the user ID from your provider's JWT and assigns it to the wallet's `owner` property. Wallet creation, transaction signing, and balance reads all work the same way regardless of which auth provider you use.

If you are just getting started or prototyping, [Crossmint Auth](/authentication/introduction) is a great way to move fast in staging before connecting your own provider.

## Prerequisites

* **API Key**: Ensure you have an API key with the scopes: `wallets.create`.

## Using your own auth provider

<Tabs>
  <Tab title="React">
    <Steps>
      <Step title="Configure JWT Authentication in the Crossmint Console">
        1. Navigate to your project in the Crossmint Console.
        2. Go to the API Keys section from the sidebar.
        3. Scroll down to the JWT authentication section.
        4. Choose your preferred authentication method:

        * **3P Auth providers**: Select from supported providers such as Auth0, Stytch, Cognito, Firebase, Kinde, or Supabase. Enter any required environment IDs or configuration details.
        * **Custom tokens**: Opt to issue and manage your own JWTs.

        5. After making your selection and providing any necessary details, click **Save JWT auth settings** to apply your configuration.

        <img src="https://mintcdn.com/crossmint/ecP9cB9MKAgXTxMF/images/wallets/jwt-authentication.png?fit=max&auto=format&n=ecP9cB9MKAgXTxMF&q=85&s=ccdf60b41ec799d4bffe7047263df7aa" alt="JWT Authentication Settings" width="1421" height="757" data-path="images/wallets/jwt-authentication.png" />
      </Step>

      <Step title="Add the Crossmint providers to your app">
        Add the necessary Crossmint providers to your app together with your own auth provider.

        <CodeGroup>
          ```tsx next.js theme={null}
          "use client";

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

          import { YourAuthProvider, useYourAuthProviderHook } from "@your-auth-provider";

          export function Providers({ children }: { children: React.ReactNode }) {
              return (
                  <YourAuthProvider>
                      <CrossmintProvider apiKey="YOUR_CLIENT_API_KEY">
                          <CrossmintWalletProvider>
                              <JwtSync />
                              {children}
                          </CrossmintWalletProvider>
                      </CrossmintProvider>
                  </YourAuthProvider>
              );
          }

          // Get the JWT from your auth provider and pass it to the Crossmint provider
          function JwtSync() {
              const { jwt } = useYourAuthProviderHook();
              const { setJwt } = useCrossmint();

              useEffect(() => {
                  setJwt(jwt);
              }, [jwt]);

              return null;
          }
          ```
        </CodeGroup>
      </Step>

      <Step title="Pass the JWT and create or retrieve the wallet">
        Once the JWT is available, use `getWallet` to retrieve an existing wallet. If no wallet exists, it throws a `WalletNotAvailableError` — catch it and call `createWallet` instead.

        <CodeGroup>
          ```tsx next.js theme={null}
          "use client";

          import { useYourAuthProviderHook } from "@your-auth-provider";
          import { useEffect } from "react";
          import { useCrossmint, useWallet } from "@crossmint/client-sdk-react-ui";
          import { WalletNotAvailableError } from "@crossmint/wallets-sdk";

          export function YourComponent() {
              const { email } = useYourAuthProviderHook();
              const { jwt } = useCrossmint();
              const { getWallet, createWallet } = useWallet();

              useEffect(() => {
                  if (email != null && jwt != null) {
                      getWallet({ chain: "base-sepolia" }).catch((error) => {
                          if (error instanceof WalletNotAvailableError) {
                              createWallet({
                                  chain: "base-sepolia",
                                  recovery: { type: "email", email },
                              }).catch(console.error);
                          }
                      });
                  }
              }, [email, jwt]);

              // your component logic here
              return (
                  <div>
                      <h1>Your Component</h1>
                  </div>
              );
          }
          ```
        </CodeGroup>

        <Note>
          `getOrCreateWallet` has been removed in V1. Use `getWallet` to retrieve an existing wallet. If it throws a `WalletNotAvailableError`, call `createWallet` instead. See the [migration guide](/wallets/guides/migrate-to-v1) for details.
        </Note>
      </Step>

      See the [React SDK reference](/sdk-reference/wallets/react/get-started) for more details on providers and hooks.
    </Steps>
  </Tab>

  <Tab title="React Native">
    <Steps>
      <Step title="Configure JWT Authentication in the Crossmint Console">
        1. Navigate to your project in the Crossmint Console.
        2. Go to the API Keys section from the sidebar.
        3. Scroll down to the JWT authentication section.
        4. Choose your preferred authentication method:

        * **3P Auth providers**: Select from supported providers such as Auth0, Stytch, Cognito, Firebase, Kinde, or Supabase. Enter any required environment IDs or configuration details.
        * **Custom tokens**: Opt to issue and manage your own JWTs.

        5. After making your selection and providing any necessary details, click **Save JWT auth settings** to apply your configuration.

        <img src="https://mintcdn.com/crossmint/ecP9cB9MKAgXTxMF/images/wallets/jwt-authentication.png?fit=max&auto=format&n=ecP9cB9MKAgXTxMF&q=85&s=ccdf60b41ec799d4bffe7047263df7aa" alt="JWT Authentication Settings" width="1421" height="757" data-path="images/wallets/jwt-authentication.png" />
      </Step>

      <Step title="Add the Crossmint providers to your app">
        Add the necessary Crossmint providers to your app together with your own auth provider.

        ```tsx theme={null}
        import { useEffect } from "react";
        import {
            CrossmintProvider,
            CrossmintWalletProvider,
            useCrossmint,
        } from "@crossmint/client-sdk-react-native-ui";

        import { YourAuthProvider, useYourAuthProviderHook } from "@your-auth-provider";

        type ProvidersProps = {
            children: React.ReactNode;
        };

        export default function Providers({ children }: ProvidersProps) {
            return (
                <CrossmintProvider apiKey="YOUR_CLIENT_API_KEY">
                    <YourAuthProvider>
                        <CrossmintWalletProvider>
                            <JwtSync />
                            {children}
                        </CrossmintWalletProvider>
                    </YourAuthProvider>
                </CrossmintProvider>
            );
        }

        // Get the JWT from your auth provider and pass it to the Crossmint provider
        function JwtSync() {
            const { jwt } = useYourAuthProviderHook();
            const { setJwt } = useCrossmint();

            useEffect(() => {
                setJwt(jwt);
            }, [jwt]);

            return null;
        }
        ```
      </Step>

      <Step title="Pass the JWT and create or retrieve the wallet">
        Once the JWT is available, use `getWallet` to retrieve an existing wallet. If no wallet exists, it throws a `WalletNotAvailableError` — catch it and call `createWallet` instead.

        ```tsx theme={null}
        import { useYourAuthProviderHook } from "@your-auth-provider";
        import { useEffect } from "react";
        import { View, Text } from "react-native";
        import { useCrossmint, useWallet } from "@crossmint/client-sdk-react-native-ui";
        import { WalletNotAvailableError } from "@crossmint/wallets-sdk";

        export function YourAuthComponent() {
            const { email } = useYourAuthProviderHook();
            const { jwt } = useCrossmint();
            const { getWallet, createWallet } = useWallet();

            useEffect(() => {
                if (jwt != null && email != null) {
                    getWallet({ chain: "base-sepolia" }).catch((error) => {
                        if (error instanceof WalletNotAvailableError) {
                            createWallet({
                                chain: "base-sepolia",
                                recovery: { type: "email", email },
                            }).catch(console.error);
                        }
                    });
                }
            }, [jwt, email]);

            // your component logic here
            return (
                <View>
                    <Text>Your Auth Component</Text>
                </View>
            );
        }
        ```

        <Note>
          `getOrCreateWallet` has been removed in V1. Use `getWallet` to retrieve an existing wallet. If it throws a `WalletNotAvailableError`, call `createWallet` instead. See the [migration guide](/wallets/guides/migrate-to-v1) for details.
        </Note>
      </Step>

      See the [React Native SDK reference](/sdk-reference/wallets/react-native/get-started) for more details on providers and hooks.
    </Steps>
  </Tab>

  <Tab title="Kotlin">
    <Steps>
      <Step title="Configure JWT Authentication in the Crossmint Console">
        1. Navigate to your project in the Crossmint Console.
        2. Go to the API Keys section from the sidebar.
        3. Scroll down to the JWT authentication section.
        4. Choose your preferred authentication method and save your settings.

        <img src="https://mintcdn.com/crossmint/ecP9cB9MKAgXTxMF/images/wallets/jwt-authentication.png?fit=max&auto=format&n=ecP9cB9MKAgXTxMF&q=85&s=ccdf60b41ec799d4bffe7047263df7aa" alt="JWT Authentication Settings" width="1421" height="757" data-path="images/wallets/jwt-authentication.png" />
      </Step>

      <Step title="Set up the SDK with your JWT">
        Initialize the SDK in your `Application.onCreate` and pass your provider's JWT to the auth manager.

        ```kotlin theme={null}
        import com.crossmint.kotlin.sdk.Crossmint
        import com.crossmint.kotlin.auth.CrossmintAuthManager
        import com.crossmint.kotlin.auth.models.AuthToken

        // In Application.onCreate:
        Crossmint.shared(apiKey = "YOUR_CROSSMINT_API_KEY", appContext = this)

        // In your composable or ViewModel:
        val sdk = LocalCrossmintSDK.current
        val authManager = sdk.authManager as CrossmintAuthManager

        // Pass the JWT from your auth provider
        authManager.authenticateWithToken(
            AuthToken(
                jwt = "YOUR_PROVIDER_JWT",
                refreshToken = "YOUR_REFRESH_TOKEN",
                userEmail = "user@example.com"
            )
        )
        ```
      </Step>

      <Step title="Create or retrieve the wallet">
        Once authenticated, create or retrieve the wallet.

        ```kotlin theme={null}
        import com.crossmint.kotlin.types.EVMChain
        import com.crossmint.kotlin.signers.SignerType

        val wallet = sdk.crossmintWallets.getWallet(chain = EVMChain.BaseSepolia)
            .getOrNull()
            ?: sdk.crossmintWallets.createWallet(
                chain = EVMChain.BaseSepolia,
                recovery = SignerType.Email("user@example.com")
            ).getOrThrow()

        println("Wallet address: ${wallet.address}")
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Swift">
    <Steps>
      <Step title="Configure JWT Authentication in the Crossmint Console">
        1. Navigate to your project in the Crossmint Console.
        2. Go to the API Keys section from the sidebar.
        3. Scroll down to the JWT authentication section.
        4. Choose your preferred authentication method and save your settings.

        <img src="https://mintcdn.com/crossmint/ecP9cB9MKAgXTxMF/images/wallets/jwt-authentication.png?fit=max&auto=format&n=ecP9cB9MKAgXTxMF&q=85&s=ccdf60b41ec799d4bffe7047263df7aa" alt="JWT Authentication Settings" width="1421" height="757" data-path="images/wallets/jwt-authentication.png" />
      </Step>

      <Step title="Set up the SDK with your JWT">
        Initialize the SDK and pass your provider's JWT to the auth manager before creating or fetching a wallet.

        ```swift theme={null}
        import CrossmintAuth
        import CrossmintClient

        // Initialize the auth manager
        let authManager = try CrossmintAuthManager(apiKey: crossmintApiKey)

        // Pass the JWT from your auth provider
        await authManager.setJWT("YOUR_PROVIDER_JWT")

        // Initialize the SDK with the auth manager
        let sdk = CrossmintSDK.shared(
            apiKey: crossmintApiKey,
            authManager: authManager
        )
        ```
      </Step>

      <Step title="Create or retrieve the wallet">
        Once the JWT is set, create or retrieve the wallet as usual.

        ```swift theme={null}
        let wallet: EVMWallet
        if let existing = try await sdk.crossmintWallets.getWallet(
            chain: EVMChain.baseSepolia,
            recovery: EVMSigners.email("user@example.com")
        ) {
            wallet = existing
        } else {
            wallet = try await sdk.crossmintWallets.createWallet(
                chain: EVMChain.baseSepolia,
                recovery: EVMSigners.email("user@example.com")
            )
        }
        print("Wallet address:", wallet.address)
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Flutter">
    <Steps>
      <Step title="Configure JWT Authentication in the Crossmint Console">
        1. Navigate to your project in the Crossmint Console.
        2. Go to the API Keys section from the sidebar.
        3. Scroll down to the JWT authentication section.
        4. Choose your preferred authentication method:

        * **3P Auth providers**: Select from supported providers such as Auth0, Stytch, Cognito, Firebase, Kinde, or Supabase. Enter any required environment IDs or configuration details.
        * **Custom tokens**: Opt to issue and manage your own JWTs.

        5. After making your selection and providing any necessary details, click **Save JWT auth settings** to apply your configuration.

        <img src="https://mintcdn.com/crossmint/ecP9cB9MKAgXTxMF/images/wallets/jwt-authentication.png?fit=max&auto=format&n=ecP9cB9MKAgXTxMF&q=85&s=ccdf60b41ec799d4bffe7047263df7aa" alt="JWT Authentication Settings" width="1421" height="757" data-path="images/wallets/jwt-authentication.png" />
      </Step>

      <Step title="Pass the JWT and create or retrieve the wallet">
        Flutter's auth client is headless. Use your own auth provider to obtain the JWT, then pass it to `client.auth.setJwt(jwt)`. The wallet controller auto-loads or creates a wallet when `createOnLogin` is configured.

        ```dart theme={null}
        import 'package:crossmint_flutter/crossmint_flutter_ui.dart';

        // Whenever your auth provider produces (or refreshes) a JWT:
        Future<void> syncCrossmintAuth(BuildContext context, String? jwt) async {
          final walletContext = CrossmintWalletContext.of(context);
          await walletContext.requireAuth.setJwt(jwt);

          // Optional — lookup or create a wallet once authenticated.
          if (jwt == null) return;
          final controller = walletContext.requireWalletController;
          final existing = await controller.getWallet(
            const CrossmintWalletLookupRequest(chain: 'base-sepolia'),
          );
          if (existing == null) {
            await controller.createWallet(
              const CrossmintWalletCreateRequest(
                chain: 'base-sepolia',
                recovery: CrossmintEmailSignerConfig(email: 'YOUR_USER_EMAIL'),
              ),
            );
          }
        }
        ```
      </Step>

      See the [Flutter SDK reference](/sdk-reference/wallets/flutter/controllers#crossmintauthclient) for details on `setJwt` and the auth client surface.
    </Steps>
  </Tab>
</Tabs>
