Sign In with Solana - Authenticate Users with their Phantom Wallet

Sign In with Solana - Authenticate Users with their Phantom Wallet

Avneesh Agarwal
·Oct 13, 2022·

4 min read

Subscribe to my newsletter and never miss my upcoming articles

Play this article

Table of contents

  • Introduction
  • Setup
  • Building the frontend
  • Creating api for validation
  • Calling the API on frontend
  • Conclusion

Introduction

In this guide, we are going to use thirdweb auth to add sign in with Solana to our Dapps!

Before we get started, below are some helpful resources where you can learn more about the tools we will use in this guide.

Let's get started!

Why use web3 sign-in?

Sign-in with Solana allows you to securely log in using a wallet and verify the wallet on the backend! We are going to use Thirdweb Auth which uses the very popular JWT standard! JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

Setup

Creating Next.js App

I am going to use the Next typescript solana starter template for this guide.

If you are following along with the guide, you can create a project with the Next TypeScript template using the thirdweb CLI:

npx thirdweb create --template next-typescript-solana-starter

If you already have a Next.js app you can simply follow these steps to get started:

  • Install the thirdweb sdks: @thirdweb-dev/react and @thirdweb-dev/sdk
  • Install packages for solana wallet adapter: @solana/wallet-adapter-react, @solana/wallet-adapter-react-ui and @solana/wallet-adapter-wallets.
  • Wrap the app in the ThirdwebProvider and WalletModalProvider.

Setting up thirdweb auth

Firstly, we need to install the thirdweb auth package:

npm i @thirdweb-dev/auth # npm

yarn add @thirdweb-dev/auth # yarn

Now, create a file called auth.config.ts and the following:

import { ThirdwebAuth } from "@thirdweb-dev/auth/next";

export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({
  privateKey: process.env.PRIVATE_KEY as string,
  domain: "example.org",
});
  • Update the domain with your domain.

  • We need the private key of our wallet. So, go to your phantom wallet (if you haven't already created one, check out this guide) and click on the top right badge and select your wallet. Then click on the export private key button:

image.png

Copy this private key, and paste it into a new file .env in the following format:

PRIVATE_KEY=<your-private-key>

Using private keys as an env variable is vulnerable to attacks and is not the best practice. We are doing it in this guide for the sake of brevity, but we strongly recommend using a secret manager to store your private key.

To configure the auth api, create a new folder inside pages/api called auth and [...thirdweb].ts file inside it! Here we need to export the thirdwebHandler that we created!

import { ThirdwebAuth } from "@thirdweb-dev/auth/next/solana";

export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({
  privateKey: process.env.PRIVATE_KEY as string,
  domain: "example.org",
});

Finally, inside the _app.tsx file, add the authConfig prop to ThirdwebProvider:

  <ThirdwebProvider
      network={network}
      authConfig={{
        authUrl: "/api/auth",
        domain: "example.org",
        loginRedirect: "/",
      }}
    >
      <WalletModalProvider>
        <Component {...pageProps} />
      </WalletModalProvider>
    </ThirdwebProvider>

Building the frontend

Inside pages/index.tsx update the return statement with the following:

return (
  <div>
    {publicKey ? (
      <button onClick={() => login()}>Sign in with Solana</button>
    ) : (
      <WalletMultiButton />
    )}
  </div>
);

We are going to use the useWallet and useLogin hooks to get the login function and user address:

const { publicKey } = useWallet();
const login = useLogin();

We need to import these hooks like this:

import { useWallet } from "@solana/wallet-adapter-react";
import { useLogin, useUser } from "@thirdweb-dev/react/solana";

This will add sign-in with Solana to our site! Now we need to check if a user exists, so for that get the user from the useUser hook like this:

const { user } = useUser();

And we will check if the user exists and if it exists we will return this:

if (user) {
  return (
    <div className={styles.container}>
      <p>You are signed in as {user.address}</p>
      <button onClick={validateUser}>Validate user</button>
    </div>
  );
}

Creating api for validation

Let's now create an api to get the user details (address) on the backend! So, create a new file called validate.ts inside pages/api and add the following:

import type { NextApiRequest, NextApiResponse } from "next";
import { getUser } from "../../auth.config";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  if (req.method === "POST") {
    const thirdwebUser = await getUser(req);

    if (thirdwebUser?.address) {
      return res.status(200).json({
        message: `You are signed in as ${thirdwebUser.address}`,
      });
    }
    return res.status(401).json({ message: "Account not validated" });
  }
  return res.status(405).json({ message: "Method not allowed" });
};

export default handler;

Here, we are using the getUser method from thirdweb to get the user's address and if it exists we send a message that "you are signed in as address".

Calling the API on frontend

Create a new function called validateUser in pages/index.tsx like this:

const validateUser = async () => {
  try {
    const response = await fetch("/api/validate", {
      method: "POST",
    });

    const data = await response.json();
    alert(data.message);
  } catch (error) {
    console.log(error);
  }
};

And attach this function to onClick of the validate button:

<button onClick={validateUser}>Validate user</button>

Conclusion

In this guide, we learned how to use thirdweb auth to add sign in with solana. Share your amazing Dapps that you built using sign in with solana on the thirdweb discord! If you want to take a look at the code, check out the GitHub Repository.

Did you find this article valuable?

Support Avneesh Agarwal by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this