Trying to build your first Web3 dapp can be a daunting challenge. An essential part of those apps is often an option to be able to log in with your wallet. An easy way to achieve this, is with the upcoming Web3Modal 2.0 release.
What are Web3Modal and Wagmi
Simply put, they are libraries to make it easier for us developers to interact with the blockchain and connect users to your dapp.
Setting up the application
We’ll start with creating our new NextJS 13 app with TS and ESLint.
npx create-next-app --experimental-app
Once in the project, we can install all the libraries we need in order to get started.
npm i @web3modal/react @web3modal/ethereum wagmi
With this out the way, we can begin with the setup of the Web3Modal client.
Getting a ProjectID from WalletConnect
To properly use Web3Modal, you need to create a project on WalletConnect.
After creating an account, simply click on New Project, pick a suitable name and then click Create.
You can now navigate into the project and find your own ProjectID
.
Now that we have the ID, we need to add it to a .env
file, so that we can use it inside the application. To do this, create a .env.local
file at the root
of your app and add the following variable. Don’t forget to insert your personal project id that you just copied. 🙂
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=<your-project-id>
Creating the Web3Modal client
In NextJS 13 the layout.tsx
is a server component by default, which is why we can’t use the required WagmiConfig Provider out of the box.
So we first need to create a web3-provider.tsx
in the apps
directory of our application with the following code.
"use client";
import { mainnet, configureChains, createClient, WagmiConfig } from "wagmi";
import {
EthereumClient,
modalConnectors,
walletConnectProvider,
} from "@web3modal/ethereum";
import { Web3Modal } from "@web3modal/react";
const chains = [mainnet];
// Wagmi client
const { provider } = configureChains(chains, [
walletConnectProvider({
projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
}),
]);
const wagmiClient = createClient({
autoConnect: true,
connectors: modalConnectors({ appName: "web3Modal", chains }),
provider,
});
// Web3Modal Ethereum Client
const ethereumClient = new EthereumClient(wagmiClient, chains);
export default function Web3ModalProvider({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<WagmiConfig client={wagmiClient}>{children}</WagmiConfig>
<Web3Modal
projectId={process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID}
ethereumClient={ethereumClient}
/>
</>
);
}
The "use client"
tells NextJS that the component should be rendered client side.
Afterwards, we configure the Web3Modal Provider by defining the chains that should be used by wagmi and passing them into the configureChains
function together with the WalletConnect provider.
This returns a provider object that we can use to create our wagmiClient
.
We also need an EthereumClient
to pass to the Web3Modal component.
This shiny new Web3 Provider can now be imported inside the root layout.tsx
file and wrapped around the children object like this.
import Web3ModalProvider from "./web3-provider";
import "./globals.css";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head />
<body>
<Web3ModalProvider>{children}</Web3ModalProvider>
</body>
</html>
);
}
Now our application is fully set up to work with Web3Modal and wagmi.
The only thing left is to create the connect button for your wallet.
Adding a connect
button
Inside the index page.tsx
all the content inside the <main></main>
tags can be removed as we don’t need it for this dapp.
The @Web3Modal/react
package provides a connect button out of the box that allows for some customisation. For this you can simply use the following code. Again, don’t forget that it’s a client side component with "use client";
"use client";
import { Web3Button } from "@web3modal/react";
export default function Home() {
return (
<main>
<Web3Button />
</main>
);
}
This completes everything we set out to do.
We can now connect our wallet to our dapp and use it as e.g. user authentication or just to fetch the wallet address.
Subscribe To Our Newsletter
Join the found3 mailing list to receive the latest news and updates from our team as soon as they are published, straight to your inbox.
You have Successfully Subscribed!
However, we can go one step further and create a fully custom connect button.
For this we’ll use TailwindCSS as our CSS framework to have some more options with the styling.
npm i -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
The new page.tsx
in the app
folder could be rewritten as:
"use client";
import { useWeb3Modal } from "@web3modal/react";
import { useAccount, useDisconnect, useBalance } from "wagmi";
export default function Home() {
const { address } = useAccount();
const { data, isLoading } = useBalance({ address });
const { open } = useWeb3Modal();
const { disconnect } = useDisconnect();
return (
<main className="absolute inset-0 grid place-content-center">
<div className="space-y-3 rounded-3xl bg-gray-800 px-8 py-6 shadow-xl">
<h1 className="font-mono text-3xl font-bold">Wallet Connect</h1>
{address ? (
<div className="space-y-8">
<div className="space-y-2">
<div className="space-y-0.5">
<h2>your address</h2>
<p className="rounded bg-gradient-to-tr from-indigo-500 to-violet-700 px-2 py-1">
{address}
</p>
</div>
<div className="space-y-0.5">
<h2>your balance</h2>
<p className="rounded bg-gradient-to-tl from-indigo-500 to-violet-700 px-2 py-1">
{isLoading
? "loading..."
: `${data?.formatted} ${data?.symbol}`}
</p>
</div>
</div>
<div className="flex w-full justify-end">
<button
type="button"
className="rounded-lg border-2 border-red-500 px-3 py-1.5 transition-colors hover:bg-gray-600/25"
onClick={() => disconnect()}
>
disconnect
</button>
</div>
</div>
) : (
<button
type="button"
onClick={() => open()}
className="w-full rounded-xl bg-gradient-to-tr from-indigo-500 to-violet-700 px-4 py-2 text-center"
>
connect wallet
</button>
)}
</div>
</main>
);
}
And with some styling in our globals.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html,
body {
@apply bg-gray-900 text-gray-100;
}
}
It would look something like this:
The final file tree should look something like this:
app/
- globals.css
- head.tsx
- layout.tsx
- page.tsx
- web3-provider.tsx
This concludes this tutorial on how to implement the functionality to connect your wallet with your dapp.
I hope you learned something along the way and were able to use this guide in your own project.
You can find the example project on my GitHub under the name web3modal-blog.