Fullstack NFT Marketplace on Ethereum with Polygon, Nextjs, Wagmi and RainbowKit

NFT marketplace on the Ethereum with Polygon and Nextjs

This project is to demonstrate how you can build Fullstack application using Polygon and Nextjs with Wagmi and Rainbowkit as Wallet Connection Manager. It would also demonstrate how to style the frontend using Chakra-UI. You could actually make use of any styling library of your choice but I have recently come to like building with Chakra but TailwindCSS is also a great library you could use. The choice of Polygon is to benefit from the lower gas transactions available on the Polygon blockchain. Polygon is one of the scaling solutions of Ethereum. Others include Arbitrum, and Optimism.

The stacks

  • Nextjs
  • Polygon
  • Infura
  • Rainbowkit
  • Hardhat
  • Etherjs

Setting up

To get started, first create a Nextjs app using the code below

npx create-next-app nftmarketplace

Change into the nftmarketplace directory and install the dependencies below:

$ yarn add ethers hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers @openzeppelin/contracts ipfs-https-client axios

We shall also be installing the wagmi, Rainbowkit and Chakra-UI libraries and apolloclient for querying the subgraph (more on this later)

yarn add @chakra-ui/react  @rainbow-me/rainbowkit@latest  @apollo/client graphql

Alternatively, you could use web3Modal to setup wallet connection but wagmi with Rainbowkit would handle all the manual process of setting up the wallet connectivity with just a simple configuration.

Create the configurations below inside your _app.js and set up the ChakraProvider, ApolloProvider and wagmi config. Wrap the configurations around the components. Replace the codes inside your _app.js with the code below:

import { ChakraProvider } from "@chakra-ui/react";
import "@rainbow-me/rainbowkit/styles.css";
import "../styles/globals.css";
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
} from "@apollo/client";
import { getDefaultWallets, RainbowKitProvider } from "@rainbow-me/rainbowkit";
import { configureChains, createClient, WagmiConfig } from "wagmi";
import { jsonRpcProvider } from "wagmi/providers/jsonRpc";
import { SUBGRAPH_URL } from "../constants";


const polygonChain = {
  id: 137,
  name: "Matic Mainnet",
  network: "polygon",
  nativeCurrency: {
    decimals: 18,
    name: "Matic",
    symbol: "MATIC",
  },
  rpcUrls: {
    default: " https://polygon-rpc.com",
  },
  blockExplorers: {
    default: {
      name: "polygonscan",
      url: "https://polygonscan.com/",
    },
  },
  testnet: false,
};

const { chains, provider } = configureChains(
  [polygonChain],
  [
    jsonRpcProvider({
      rpc: (chain) => {
        if (chain.id !== polygonChain.id) {
          throw new Error("Error! Switch your network to Polygon Mainnnet");
          return null;
        };
        return { http: chain.rpcUrls.default };
      },
    }),
  ]
);

const { connectors } = getDefaultWallets({
  appName: "Eth NFTMarketplace",
  chains,
});

const wagmiClient = createClient({
  autoConnect: true,
  connectors,
  provider,
});

const appolloClient = new ApolloClient({
  uri: SUBGRAPH_URL,
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }) {
  return (
    <ApolloProvider client={appolloClient}>
    <WagmiConfig client={wagmiClient}>
      <RainbowKitProvider chains={chains}>

        <ChakraProvider>
          <Component {...pageProps} />
        </ChakraProvider>

      </RainbowKitProvider>
    </WagmiConfig>
    </ApolloProvider>
  );
}

export default MyApp;

You would notice we have a variable inside a constants file. We shall come back to this later.

Setup Hardhat

Before we proceed with building out the functionalities, let us configure Hardhat, the Solidity development environment. On your terminal, change to the nftmarketplace directory and run the initialize a new hardhat enviroment

npx hardhat

? What do you want to do? Create a basic sample project
? Hardhat project root: <Choose default path>

888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

Welcome to Hardhat v2.11.2

✔ What do you want to do? · Create a JavaScript project
✔ Hardhat project root: · /home/sunday/dev/projects/fullstack-nft-marketplace/nftmarketplace

✔ Do you want to add a .gitignore? (Y/n) · y
We couldn't initialize the sample project because this file already exists: README.md

Please delete or move them and try again.

If you get the error above, delete the README.md and initialize hardhat again. Hardhat when initialized creates below files at the root of your project:

  • hardhat.config.js: This is the configuration file for specifying the network to connect including plugins and custom tasks
  • scripts: Used to deploy the contract
  • tests folder: A folder containing example test cases
  • contracts: Contains a sample contract

We shall be modifying first the hardhat.config.js file first. Replace the contents of the file with the codes below:

/* hardhat.config.js */
require("@nomiclabs/hardhat-waffle")

module.exports = {
  defaultNetwork: "hardhat",
  networks: {
    hardhat: {
      chainId: 1337
    },
 mumbai: {
   url: "https://rpc-mumbai.maticvigil.com",
   accounts: [process.env.privateKey]
 }
  },
  solidity: {
    version: "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      }
    }
  }
}

We configure

Next install the dotenv

yarn add dotenv

Create the Smart Contract

Here are the requirements for the NFT Marketplace smart contract

  • When a user lists an NFT for sale, the NFT ownership is transferred to the contract address from the creator
  • When a user or buyer buys an NFT, the price of the NFT is transferred to the seller while the ownership of the NFT transferred to the buyer
  • The contract owner can set a listing fee which earns him commission from any successful purchase. The commission is deducted from the NFT price and the price less the fee is credited to the seller

Now let's start creating the smart contract. Inside the root of your project, open the contract folder and remove the file created by hardhat init, Lock.sol. Create a new file and call it NFTMarketplace.sol