• Stars
    star
    161
  • Rank 233,470 (Top 5 %)
  • Language
    TypeScript
  • License
    Apache License 2.0
  • Created over 2 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Restrict access to content based on the ownership of an NFT

Token Gated Website

This project demonstrates how you can restrict content on your website to only those users who own a token of your choice (any ERC-20, ERC-721 or ERC-1155).

You can use any token you like regardless if it's deployed using thirdweb or not. However, if the contract wasn't deployed on thirdweb initially, make sure you import the contract on the thirdweb dashboard.

Installation

Install the template with thirdweb create

npx thirdweb create --template nft-gated-website

Set up

  • Deploy or import an already deployed token contract on thirdweb dashboard.
  • Update the information in the yourDetails.js file to use your contract address and auth domain name.

Environment Variables

To run this project, you will need to add the following environment variables to your .env file:

THIRDWEB_AUTH_PRIVATE_KEY=
NEXT_PUBLIC_TEMPLATE_CLIENT_ID=
TW_SECRET_KEY=
  • Generate your TW_SECRET_KEY and NEXT_PUBLIC_TEMPLATE_CLIENT_ID via thirdweb's dashboard.
  • For THIRDWEB_AUTH_PRIVATE_KEY export your wallet private key from your wallet.

Run Locally

Install dependencies:

  yarn

Start the server:

  yarn start

How It Works

Using Auth, we can verify a user's identity on the server-side, by asking them to sign a message and verify they own the wallet they claim to be, and validating the signature.

When we verified the user's identity on the server-side, we check their wallet to see if they have an NFT from our collection. We can then serve different content and restrict what pages they can access based on their NFT balance.

// This is the chain your dApp will work on.
const activeChain = "mumbai";

function MyApp({ Component, pageProps }) {
  return (
    <ThirdwebProvider
      activeChain={activeChain}
      authConfig={{
        domain: domainName,
        authUrl: "/api/auth",
      }}
    >
      <Head>
        <title>NFT Gated Website</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta
          name="description"
          content="Learn how to use the thirdweb Auth SDK to create an NFT Gated Website"
        />
      </Head>
      <Component {...pageProps} />
    </ThirdwebProvider>
  );
}

export default MyApp;

Next, we need to create a configuration file that contains our wallet's private key (used to generate messages for users to sign) and our site's domain name:

This file is called auth.config.js and is at the root of the project.

import { ThirdwebAuth } from "@thirdweb-dev/auth/next";
import { PrivateKeyWallet } from "@thirdweb-dev/auth/evm";
import { domainName } from "./const/yourDetails";

export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({
  domain: domainName,
  wallet: new PrivateKeyWallet(process.env.THIRDWEB_AUTH_PRIVATE_KEY || ""),
});

Finally, we have a catch-all API route called pages/api/auth/[...thirdweb].js, which exports the ThirdwebAuthHandler to manage all of the required auth endpoints like login and logout.

import { ThirdwebAuthHandler } from "../../../auth.config";

export default ThirdwebAuthHandler();

Restricting Access

To begin with, the user will reach the website with no authentication.

When they try to access the restricted page (the / route), we use getServerSideProps to check two things:

  1. If the user is currently authenticated (using getUser).
  2. If the user's wallet balance is greater than minTokensRequired provided in yourDetails.js of the NFTs in our NFT collection.

If either of these checks is false, we redirect the user to the /login page before they are allowed to access the restricted page.

Let's break that down into steps:

Setting Up the Auth SDK

Inside the _app.jsx file, we configure the Auth SDK in the ThirdwebProvider component that wraps our application, allowing us to use the hooks of the SDK throughout our application:

Checking For Authentication Token

First, we check if this user has already been authenticated.

If this is the first time the user has visited the website, they will not have an access_token cookie.

// This gets called on every request
export async function getServerSideProps(context) {
  const user = await getUser(context.req);

  if (!user) {
    return {
      redirect: {
        destination: "/login",
        permanent: false,
      },
    };
  }

  // ...
}

If the user is not authenticated, then we don't check the user's wallet balance; we just immediately redirect them to the /login page.

If there is a detected user from getUser, we can then check their balance.

Checking Wallet Balance

Now we're ready to check the user's wallet balance.

To do this, we have created a utility function called checkBalance that we can use to check the user's balance for a given NFT.

import { isFeatureEnabled } from "@thirdweb-dev/sdk";
import {
  contractAddress,
  erc1155TokenId,
  minimumBalance,
} from "../const/yourDetails";

export default async function checkBalance(sdk, address) {
  const contract = await sdk.getContract(
    contractAddress // replace this with your contract address
  );

  let balance;

  if (isFeatureEnabled(contract.abi, "ERC1155")) {
    balance = await contract.erc1155.balanceOf(address, erc1155TokenId);
  } else if (isFeatureEnabled(contract.abi, "ERC721")) {
    balance = await contract.erc721.balanceOf(address);
  } else if (isFeatureEnabled(contract.abi, "ERC20")) {
    balance = (await contract.erc20.balanceOf(address)).value;
    return balance.gte((minimumBalance * 1e18).toString());
  }

  // gte = greater than or equal to
  return balance.gte(minimumBalance);
}

This function will check the type of contract being used, check the balance accordingly and returns true or false that we can store in a variable:

const hasNft = await checkBalance(sdk, address);

Here's our final check, if the user has a balance of 0, then we redirect them to the /login page.

// If they don't have an NFT, redirect them to the login page
if (!hasNft) {
  return {
    redirect: {
      destination: "/login",
      permanent: false,
    },
  };
}

If the user gets past these checks, then we allow them to view the restricted page.

// Finally, return the props
return {
  props: {},
};

Signing In

We've now successfully restricted access to our home page, now let's explore the /login page.

We use the ConnectWallet component to handle the connection to the user's wallet, signing in, and signing out.

<ConnectWallet />

Additional Resources

Contributing

Contributions and feedback are always welcome!

Please visit our open source page for more information.

Need help?

For help, join the discord or visit our support page.

More Repositories

1

catattacknft

Claim your cat, attack others, and accumulate points to win!
TypeScript
114
star
2

nft-staking-app

An NFT Staking contract deployed using thirdweb deploy, where users stake their ERC721 tokens and earn ERC20 tokens in return!
TypeScript
93
star
3

nft-drop

Create your own custom NFT minting page using thirdweb's NFT Drop contract
TypeScript
82
star
4

next-typescript-starter

thirdweb starter project with Next.js & TypeScript
TypeScript
69
star
5

marketplace

An NFT Marketplace where you can list NFTs for direct sale or for auction. Users can come and bid on your listings or buy your NFTs, similar to OpenSea.
TypeScript
60
star
6

signature-based-minting

Create a community-made NFT collection with restrictions that you specify using signature based minting in thirdweb's NFT Collection contract.
TypeScript
49
star
7

thirdweb-stripe

Subscription based payments for web3 apps using thirdweb authentication and stripe
TypeScript
44
star
8

play-to-earn-game

Use thirdweb's token, edition drop, and a custom contract using thirdweb deploy to build a Play-to-Earn game!
TypeScript
40
star
9

next-javascript-starter

thirdweb starter project with Next.js & JavaScript
JavaScript
34
star
10

telegram-mini-app

Thirdweb's in-app wallets in Telegram using custom authentication.
TypeScript
30
star
11

cra-javascript-starter

thirdweb starter project with Create React App & JavaScript
JavaScript
30
star
12

lens

Starter kit for using Lens Protocol with the thirdweb SDK!
TypeScript
28
star
13

pwa-demo

TypeScript
23
star
14

login-with-wallet

Authenticate to a backend using the sign in with ethereum standard provided by thirdweb auth
TypeScript
21
star
15

dao

Build a DAO using thirdweb's vote, token, and edition drop contracts.
JavaScript
20
star
16

marketplace-template

Build your own NFT Marketplace with thirdweb SDKs
TypeScript
19
star
17

community-rewards

Reward your community using NFTs and thirdweb's signature based minting.
JavaScript
19
star
18

next-starter

Starter kit to build with Next and thirdweb without additional initial configuration.
TypeScript
19
star
19

magic-link

Connect users to your dApp using just their email using thirdweb's useMagic hook!
TypeScript
18
star
20

marketplace-v3

Create your own NFT marketplace where users can buy and sell NFTs!
TypeScript
17
star
21

thirdweb-auth-next

Enable wallet-based login with thirdweb Auth & Next
TypeScript
16
star
22

multiwrap

Wrap ERC-1155, ERC-721 and ERC-20 tokens in to one ERC-721 token
JavaScript
15
star
23

contract-hub

Demonstration of all thirdweb's pre-built contracts with TypeScript + Getting started snippets
TypeScript
15
star
24

web3button

Learn how to use the Web3Button component from the thirdweb React SDK!
JavaScript
15
star
25

thirdweb-auth-supabase

Enable users to login to your backend with their wallet, and store users in supabase.
TypeScript
15
star
26

cra-typescript-starter

thirdweb starter project with Create React App & TypeScript
TypeScript
15
star
27

thirdweb-auth-next-auth

Enable wallet-based login with thirdweb Auth & Next Auth
TypeScript
14
star
28

signature-drop

Use the signature drop pre-built contract to claim NFTs under a claim phase as well as claim using signature-based minting!
TypeScript
14
star
29

firebase-auth

Integrate sign in with Ethereum using thirdweb Auth into your Firebase application
TypeScript
13
star
30

creator-platform

Authenticate users into a web2 database to build a hybrid web2+web3 creator platform!
TypeScript
12
star
31

github-contributor-nft-rewards

Use signature-based minting to allow users who have contributed to your github repositories to claim an NFT!
TypeScript
11
star
32

seamless-stripe-checkout

Use Magic.link to authenticate users using their email, then we use stripe to collect payment for the NFTs and send them to the user's wallet generated by Magic.
TypeScript
10
star
33

next-typescript-solana-starter

Starter Kit for Next.js + TypeScript + Solana
TypeScript
10
star
34

burn1155-mint721

Similar to the MAYC collection, allow users who hold an NFT from your original NFT Collection to burn an ERC-1155 NFT collection to claim an NFT from your new NFT Collection!
CSS
10
star
35

shopify-discount-codes

Grant users who hold an NFT from your collection a discount code they can use in your Shopify store!
TypeScript
9
star
36

marketplace-with-signature-based-minting

Mint and list NFTs on to a marketplace using signature-based minting
JavaScript
9
star
37

discord-role-granter

Grant users who own NFTs a role in your Discord server!
TypeScript
9
star
38

mintcaster

Bootstrap your own client on Farcaster — with a feed, cast functionality, and Sign-in with Farcaster auth. Add NFT minting functionality with thirdweb Engine.
TypeScript
8
star
39

edition-drop

Starter kit for using the Edition Drop Pre-Built contract
TypeScript
8
star
40

unity-blockventure

Unity SDK Starter Template - Lite RPG Gathering, Shopping and Trading Systems.
JavaScript
8
star
41

shopify-sell-nfts

Sell NFTs in FIAT currency using a Shopify store and webhooks!
JavaScript
8
star
42

hardhat-typescript-starter

thirdweb contracts starter project for Hardhat & TypeScript
TypeScript
7
star
43

pwa-vite-typescript-starter

TypeScript
7
star
44

unity-rpg-game

Speak with NPCs and complete quests to earn ERC20 tokens which you can use to buy NFTs from the in-game shop!
C#
7
star
45

nft-gated-website-solana

Restrict access to content on your website to NFT Holders in Solana!
TypeScript
7
star
46

react-native-typescript-starter

Java
6
star
47

hardhat-javascript-starter

thirdweb contracts starter project for Hardhat & TypeScript
JavaScript
6
star
48

solana-hub

Explore what you can do with our Solana SDK!
TypeScript
6
star
49

connect-wallet-button

Learn how to use the ConnectWallet Button component from the React SDK!
JavaScript
6
star
50

unity-nft-lootboxes

Purchase NFT loot boxes from a marketplace and open them to reveal randomly selected NFTs inside!
JavaScript
6
star
51

full-stack-web3-app

Build an application on top of a custom contract using the thirdweb SDK
JavaScript
6
star
52

erc721staking-lockup

NFT Staking contract with lockup period
TypeScript
6
star
53

token-drop

Release your token with claim conditions for a price using thirdweb's Token Drop contract
TypeScript
6
star
54

thirdweb-auth-express-v4

Enable wallet-based login with thirdweb Auth & Express
TypeScript
5
star
55

thirdweb-bundlr

Decentralized NFT metadata storage using Bundlr
TypeScript
5
star
56

unlock-subscribe

Build a simple on-chain subscription model into your app using the Lock contract by Unlock
CSS
5
star
57

makeswift

Use Makeswift to build a web3 application using a drag-and-drop web builder
TypeScript
5
star
58

mint-specific-nft

Allow users to choose which NFT they want to mint from the collection
TypeScript
5
star
59

engine-express

TypeScript
5
star
60

unreal_demo

Unreal thirdweb engine demo
C++
5
star
61

solana-nft-gallery

Build an NFT Gallery showcasing all of your collection's NFTs on Solana!
TypeScript
5
star
62

vite-typescript-starter

thirdweb starter project with Vite & TypeScript
TypeScript
5
star
63

reddit

Create a seamless user experience with email sign in and pay the gas for minting NFTs.
TypeScript
4
star
64

forge-starter

thirdweb contracts starter project for Forge
Solidity
4
star
65

custom-dashboard

Use thirdweb's sdk.deployer to deploy any pre-built contract dynamically with no private keys!
TypeScript
4
star
66

engine-chat-ai

TypeScript
4
star
67

unity-karting-game

Purchase Vehicle NFTs from an in-game marketplace and start earning ERC20 tokens used to buy upgrades!
C#
4
star
68

thirdweb-circle-cctp

TypeScript
4
star
69

thirdweb-auth-solana-next

Enable wallet-based login for Solana wallets with thirdweb Auth & Next
TypeScript
4
star
70

solana-token-deploy

Deploy a token program using the TypeScript SDK
JavaScript
4
star
71

artblocks

Create Generative Art NFTs with centralized metadata using the Contracts SDK
JavaScript
4
star
72

phaser-platformer

TypeScript
4
star
73

sign-in-with-solana

Verify a user owns their wallet in a server-side environment using Sign In With Solana!
TypeScript
4
star
74

airdrop-nfts-to-holders

Airdrop ERC1155 NFTs to wallet addresses that hold an NFT from your ERC721 Collection!
JavaScript
4
star
75

vite-javascript-starter

thirdweb starter project with Vite & JavaScript
JavaScript
4
star
76

updatable-nft-metadata

JavaScript
3
star
77

smart-wallet-react

Connecting and interacting using smart wallets in a React app
JavaScript
3
star
78

covalent

Load the tokens a wallet owns using the covalent API
CSS
3
star
79

react-native-nft-drop

Java
3
star
80

thirdweb-auth-flask

Enable wallet-based login with thirdweb Auth & Flask
TypeScript
3
star
81

next-javascript-solana-starter

Starter Kit for Next.js + JavaScript + Solana
JavaScript
3
star
82

express-javascript-solana-starter

Starter template for Express.js and the thirdweb Solana SDK.
JavaScript
3
star
83

edition-staking-app

ERC1155 NFT Staking smart contract and web application. Allow users to stake their edition NFTs and earn erc20 tokens as reward!
TypeScript
3
star
84

packs

Bundle NFTs and Tokens together in Packs that users can open and receive randomly selected tokens from those that were bundled!
TypeScript
3
star
85

phygital-experience

JavaScript
3
star
86

vite-starter

Starter template to build onchain applications with thirdweb and vite.
TypeScript
3
star
87

node-typescript-solana-starter

Starter template for Node.js, TypeScript and the thirdweb Solana SDK
TypeScript
2
star
88

go-signature-mint

Go
2
star
89

3d-asset-nft-script

Use the SDK to mint 3D asset NFTs for your Unity games!
TypeScript
2
star
90

getting-started

Get started with thirdweb by building and deploying a full project including a smart contract and react application.
JavaScript
2
star
91

unity-vr

Create VR Games in Unity using GamingKit
C#
2
star
92

thirdweb-chainlink-functions

Off-chain Data & Computation with Chainlink Functions
Solidity
2
star
93

gated-content-example

TypeScript
2
star
94

thirdweb-chainlink-template

Solidity
2
star
95

thirdweb-auth-fiber

Enable wallet-based login with thirdweb Auth & Fiber
TypeScript
2
star
96

anvil-local-node

Burn to Evolve NFT contract with front-end. Deployed and tested on Anvil local node
Solidity
2
star
97

solidity-hello-world

Build and deploy a simple hello world smart contract using our contract kit!
JavaScript
2
star
98

sign-in-button

Simple starter kit for Auth and the ConnectWallet button
JavaScript
2
star
99

auth-with-supabase

TypeScript
2
star
100

connect-embed-next

ConnectEmbed component usage in Next.js
TypeScript
2
star