Clerk logo

Clerk Docs

Ctrl + K
Go to clerkstage.dev

Get started with Web3

Learn to install and initialize Clerk in a new Web3 application.

Overview

Clerk is the easiest way to add Web3 authentication to your application. This guide will walk you through the necessary steps to install and use Web3 authentication in a new Next.js application. After following this guide, you should have a working Next.js app complete with:

  • Web3 authentication
  • Session management
  • Self-serve multifactor authentication
  • Self-serve profile enrichment

Before you start

You need to create a Clerk Application in your Clerk Dashboard. Configure the application to use "Sign in with Metamask"

Choose the "Sign in with Metamask" authentication strategy

Creating a new Next.js app

Start by creating a new Next.js application - this is usually done using the CLI

1
npx create-next-app
1
yarn create next-app

If you wish to use TypeScript, just add --typescript to the commands above. Clerk is written in TypeScript, so it works out of the box without any extra configuration. For more information, you can reference the Next.js documentation.

Installing Clerk

Once you have a Next.js app ready, you need to install the Clerk React SDK. This will give you access to our prebuilt Clerk Components and React hooks.

1
# Navigate to your application's root directory
2
cd yourapp
3
4
# Install the clerk/nextjs package
5
npm install @clerk/nextjs
1
# Navigate to your application's root directory
2
cd yourapp
3
4
# Install the clerk/nextjs package
5
yarn add @clerk/nextjs

Add your .env

.env.local
1

To run your app, start the development server and navigate to http://localhost:3000.

1
npm run dev
1
yarn dev

For more details, consult the Clerk React installation page.

Adding <ClerkProvider />

Clerk requires your application to be wrapped in the <ClerkProvider/> component. In Next.js, we add this in pages/_app.js.

1
import { ClerkProvider } from '@clerk/nextjs';
2
3
function MyApp({ Component, pageProps }) {
4
5
return (
6
// Wrap your entire app with ClerkProvider
7
<ClerkProvider>
8
<Component {...pageProps} />
9
</ClerkProvider>
10
);
11
}
12
13
export default MyApp;

<ClerkProvider/> from the @clerk/nextjs package is already configured to using the same routing logic with Next.js. This makes sure that navigating between subpages and when navigating to callback URLs, routing remains consistent.

Requiring Web3 authentication

The easiest way to require authentication before showing a protected page is to use our Control Components:

  • <SignedIn/>: Renders its children only when a user is signed in.
  • <SignedOut/>: Renders its children only when there's no active user.

As a child of <SignedOut/>, we will include our <SignInWithMetamaskButton/> so the user can trigger the Metamask authentication flow.

The following example shows you how to compose our flexible Control Components to build authentication flows that match your needs. Please note that you don't need to use any additional APIs, everything shown below is just Javascript.

_app.js
1
import '../styles/globals.css'
2
import { ClerkProvider, SignedIn, SignedOut, SignInWithMetamaskButton } from '@clerk/nextjs';
3
import { useRouter } from 'next/router';
4
5
// List pages you want to be publicly accessible, or leave empty if
6
// every page requires authentication. Use this naming strategy:
7
// "/" for pages/index.js
8
// "/foo" for pages/foo/index.js
9
// "/foo/bar" for pages/foo/bar.js
10
// "/foo/[...bar]" for pages/foo/[...bar].js
11
const publicPages = [];
12
13
function MyApp({ Component, pageProps }) {
14
// Get the pathname
15
const { pathname } = useRouter();
16
17
// Check if the current route matches a public page
18
const isPublicPage = publicPages.includes(pathname);
19
20
// If the current route is listed as public, render it directly
21
// Otherwise, use Clerk to require authentication
22
return (
23
<ClerkProvider>
24
{isPublicPage ? (
25
<Component {...pageProps} />
26
) : (
27
<>
28
<SignedIn>
29
<Component {...pageProps} />
30
</SignedIn>
31
<SignedOut>
32
<SignInWithMetamaskButton />
33
</SignedOut>
34
</>
35
)}
36
</ClerkProvider>
37
);
38
}
39
40
export default MyApp;

Visit http://localhost:3000 to see your page. The home "/" page is not listed in the publicPages array, so you'll immediately see the Sign in with Metamask button - go ahead and try it!

Hello, world!

After signing in with Metamask, you'll be presented with the Next.js default start screen. Let's update pages/index.js to retrieve add a UserButton and retrieve the current users Metamask address:

1
import { UserButton, useUser } from "@clerk/nextjs";
2
3
export default function Home() {
4
const { primaryWeb3Wallet } = useUser();
5
return (
6
<>
7
<header
8
style={{
9
display: "flex",
10
justifyContent: "space-between",
11
padding: "1rem",
12
}}
13
>
14
<span>My first DApp</span>
15
<UserButton />
16
</header>
17
<main style={{ padding: "1rem" }}>
18
<p>Address: {primaryWeb3Wallet.web3Wallet}</p>
19
</main>
20
</>
21
);
22
}

Accessing the Web3 address from the backend

Add authentication to a serverless API route

A new Next.js app comes with a sample API route in /pages/api/hello.js. Let's modify it to retrieve the user's Web3 address:

1
import { requireSession } from "@clerk/nextjs/api";
2
3
export default requireSession(async (req, res) => {
4
try {
5
// SDK helpers for this request are coming soon!
6
const user = await fetch(
7
`https://api.clerk.dev/v1/users/${req.session.userId}`,
8
{
9
headers: { Authorization: `Bearer ${process.env.CLERK_SECRET_KEY}` },
10
}
11
).then((r) => r.json());
12
13
// Retrieve the address
14
const address = user.web3_wallets[0].web3_wallet;
15
res.status(200).json({ address: address });
16
} catch (e) {
17
console.log(e);
18
res.status(500).json({
19
error: "Something went wrong retrieving the web3wallet from Clerk",
20
});
21
}
22
});

Next steps

You now have Web3 authentication on a new Next.js application, and you know how to retrieve the user's Web3 address from both the frontend and the backend.

Was this helpful?

Clerk © 2023