Connect wallet using Email ID

Connect wallet using Email ID

Use Thirdweb and Magic link to connect users using email id.

·

6 min read

Problem

One of the major problems right now in web3 is onboarding new users, if you've used a Dapp before you know how complicated it can get sometimes to create a new wallet -> store the seed phrase -> store the private keys -> keep them safe, and there's a lot more to this. Users usually get overwhelmed by all this, but you don't need to now, Magic has actually found a solution for the problem, this could help onboard people just using their email ID, you don't believe it? try it out yourself over here -> Live Demo.

Intro

In this guide, we'll learn how to let users create and connect a wallet using an email id. We will be using Thirdweb's useMagic hook which leverages Magic's ability to create a wallet on the user's behalf(custodial wallet) and connect it to your Dapp. We will also be using Next JS in this guide but feel free to use a framework of your choice.

Overview

Here's what we are going to do:

  1. Install Next JS
  2. Install thirdweb libraries
  3. Setup magic.link account
  4. Build our UI
  5. Configure the app
  6. Wire up all the functions

Building the app

1. Install Next JS

npx create-next-app@latest magic-wallet-create

This will create a folder magic-wallet-create with all the required dependencies for Next JS.

2. Install thirdweb libraries

npm install @thirdweb-dev/react @thirdweb-dev/sdk ethers

Then, run the development server:

npm run dev

Open localhost:3000 with your browser to see the result. At the moment, you'll only see some boilerplate Next JS code but we'll work on it next.

For this project, we will use Tailwind to style our components. You can just paste this cdn link tag in the head of index.js:

<Head>
      <title>Thirdweb X Magic</title>
      <meta name="description" content="Connect wallet using email ID" />
      <link rel="icon" href="/favicon.ico" />
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" integrity="sha512-wnea99uKIC3TJF7v4eKk4Y+lMz2Mklv18+r4na2Gn1abDRPPOeef95xTzdwGD9e6zXJBteMIhZ1+68QC5byJZw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
 </Head>

Go on to Magic.link and click on Get started on top right corner, this will take you to a sign up page create an account and you'll see this page.

image.png

If you're wondering why I didn't hide my API keys, don't worry I'll delete it later. Also, you can change the name of your app through the settings and there are also other customizations that you can play around with.

Now just copy the PUBLISHABLE API KEY and save it for later we'll use it in our app to connect to your magic app.

4. Build UI

I'll share the repo of the finished project at the end for you to copy the frontend code, but I'll also paste a few snippets so you can get the vibe of the code. This will be the pages/index.js, not much over here just basic jsx and css.

import React, { useRef } from 'react'

import Head from 'next/head'

const Home = () => {

  return (
    <div>
      <Head>
        <title>Magic Link Wallet connect</title>
        <meta name="description" content="Magic Link and Thirdweb Email wallet connect" />
        <link rel="icon" href="/favicon.ico" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" referrerpolicy="no-referrer" />
      </Head>

      <main className="absolute top-2/4 left-2/4 text-center" style={{transform: 'translate(-50%, -50%)'}}>
            <div>
              <h1 className="text-3xl font-bold text-center">Connect wallet with Email using Magic link</h1>

              <form onSubmit={(e) => handleSubmit(e)} className='flex justify-center'>
                <input className='my-2 p-2 rounded-lg w-2/4 border' type="email" ref={email} placeholder="Enter your email id" />
                <button className='my-2 ml-2 p-2 rounded-lg border shadow bg-black text-white hover:bg-white hover:text-black' type='submit'>Connect Wallet</button>
              </form>
            </div>
      </main>

      <footer className="fixed bottom-0 w-full p-4 flex items-center justify-center border-t shadow">
        <a
          href="https://github.com/Deveshb15/magic-wallet-create"
          target="_blank"
          rel="noopener noreferrer"
        >
          Devesh B
        </a>
      </footer>
    </div>
  )
}

export default Home

5. Configure the app

First, we'll create a .env file in the root folder and store our Magic PUBLISHABLE API KEY, something like this:

NEXT_PUBLIC_MAGIC_API_KEY=pk_live_FEA45618BC84E329

we need to add NEXT_PUBLIC on the env variables for the browser to detect them and also make sure to restart the server once env variables are added. Next, we'll set up our pages/_app.js with thirdweb Provider.

import '../styles/globals.css'
import { ChainId, ThirdwebProvider } from '@thirdweb-dev/react'

const activeChainId = ChainId.Mumbai

const magicWalletConnector = {
  name: 'magic',
  options: {
    // Replace this with your own magic link api key
    apiKey: process.env.NEXT_PUBLIC_MAGIC_API_KEY,
    rpcUrls: {
      [ChainId.Mumbai]: "https://mumbai.magic.io/rpc",
    },
  },
}

const connectors = [magicWalletConnector]

function MyApp({ Component, pageProps }) {
  return (
      <ThirdwebProvider desiredChainId={activeChainId} walletConnectors={connectors}>
        <Component {...pageProps} />
      </ThirdwebProvider>
  )
}

export default MyApp

Here we create a activeChainId variable and set it to polygon mumbai testnet and then we'll configure the Magic Link Wallet Connector. For connectors instead of injected which is metamask, we'll use magic wallet connector. After this, we'll hook all this with the ThirdwebProvider and wrap it around the Components so that entire app will be able to access it.

6. Wire up all the functions

Let's wire up everything in index.js. First let's import all the required functions from the libraries:

import React, { useRef } from 'react'
import { useAddress, useMagic, useDisconnect } from '@thirdweb-dev/react'
import Head from 'next/head'

Next, let's just initialize them:

const address = useAddress()
const connectWithMagic = useMagic()
const disconnect = useDisconnect()

const email = useRef("")

Let's write the handleSubmit function for the form submission:

const handleSubmit = (e) => {
    e.preventDefault()
    console.log(email.current.value)
    if(email.current.value.length > 0) {
      connectWithMagic({ email: email.current.value})
    }
  }

here we use connectWithMagic function which is basically the useMagic hook provided by thirdweb, we provide it the email entered by the user in the input field.

There's just one change left to make now, let's change the main tag in index.js to show the connected address of the user once he get's connected with email ID:

<main className="absolute top-2/4 left-2/4 text-center" style={{transform: 'translate(-50%, -50%)'}}>
        {
          address ? (
            <div>
              <h1 className="text-3xl font-bold text-center">Wallet Connected🥳</h1>
              <div className='py-1'>
                <p className='text-black'>Your wallet address: {address}</p>
                <button onClick={() => disconnect()} className='my-2 ml-2 p-2 rounded-lg border shadow bg-black text-white hover:bg-white hover:text-black'>Disconnect</button>
              </div>
            </div>
          ) : (
            <div>
              <h1 className="text-3xl font-bold text-center">Connect wallet with Email using Magic link</h1>
              <form onSubmit={(e) => handleSubmit(e)} className='flex justify-center'>
                <input className='my-2 p-2 rounded-lg w-2/4 border' type="email" ref={email} placeholder="Enter your email id" />
                <button className='my-2 ml-2 p-2 rounded-lg border shadow bg-black text-white hover:bg-white hover:text-black' type='submit'>Connect Wallet</button>
              </form>
            </div>
          )
        }
</main>

In this we provide user to disconnect wallet using the useDisconnect hook and show him address using useAddress hook by thirdweb.

Entire index.js page:

import React, { useRef } from 'react'
import { useAddress, useMagic, useDisconnect } from '@thirdweb-dev/react'

import Head from 'next/head'

const Home = () => {

  const address = useAddress()
  const connectWithMagic = useMagic()
  const disconnect = useDisconnect()

  const email = useRef("")

  const handleSubmit = (e) => {
    e.preventDefault()
    console.log(email.current.value)
    if(email.current.value.length > 0) {
      connectWithMagic({ email: email.current.value})
    }
  }

  return (
    <div>
      <Head>
        <title>Magic Link Wallet connect</title>
        <meta name="description" content="Magic Link and Thirdweb Email wallet connect" />
        <link rel="icon" href="/favicon.ico" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" referrerpolicy="no-referrer" />
      </Head>

      <main className="absolute top-2/4 left-2/4 text-center" style={{transform: 'translate(-50%, -50%)'}}>
        {
          address ? (
            <div>
              <h1 className="text-3xl font-bold text-center">Wallet Connected🥳</h1>
              <div className='py-1'>
                <p className='text-black'>Your wallet address: {address}</p>
                <button onClick={() => disconnect()} className='my-2 ml-2 p-2 rounded-lg border shadow bg-black text-white hover:bg-white hover:text-black'>Disconnect</button>
              </div>
            </div>
          ) : (
            <div>
              <h1 className="text-3xl font-bold text-center">Connect wallet with Email using Magic link</h1>

              <form onSubmit={(e) => handleSubmit(e)} className='flex justify-center'>
                <input className='my-2 p-2 rounded-lg w-2/4 border' type="email" ref={email} placeholder="Enter your email id" />
                <button className='my-2 ml-2 p-2 rounded-lg border shadow bg-black text-white hover:bg-white hover:text-black' type='submit'>Connect Wallet</button>
              </form>
            </div>
          )
        }
      </main>

      <footer className="fixed bottom-0 w-full p-4 flex items-center justify-center border-t shadow">
        <a
          href="https://github.com/Deveshb15/magic-wallet-create"
          target="_blank"
          rel="noopener noreferrer"
        >
          Devesh B
        </a>
      </footer>
    </div>
  )
}

export default Home

That's it

Awesome🥳 the app is complete and ready to be deployed, you can checkout the final code over here Github Repo and finally deploy the app. You can reach out to me on my twitter Deveshb15 if you need any help.

Good luck and happy building!

Did you find this article valuable?

Support Devesh's Blog by becoming a sponsor. Any amount is appreciated!