Photo by Choong Deng Xiang on Unsplash
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