How to create your NFT Marketplace using Express Protocol!
This tutorial guides you to create a custom NFT marketplace dApp without writing the smart contracts from scratch. Instead, we will be using the Express Protocol SDK which is built on top of open and secured Smart Contracts and deployed on multiple blockchains.
So without any further ado, let’s quickly jump into it.
Prerequisites
The following tools will be used in the tutorial -
- Node.js
- Metamask extension.
- Parcel-bundler
- Express-Protocol-SDK
Getting Started
The first step is to install Node.js (≥16 version) if you do not have it already. You can use this link to find the installer.
Now head up to your favorite code editor (obviously VS Code) and initiate an NPM project in an empty directory with npm init -y
After the project is initialized, we will install the Express-Protocol-SDK.
npm install pandora-express
We will also require to install parcel-bundler globally for bundling our application.
npm install -g parcel-bundler
With all this in place, we are ready to proceed with creating our NFT Marketplace dApp.
Creating the Frontend
Since this is not a tutorial for writing the best frontend, we will be using vanilla-javascript(and that’s why we are using a bundler) for creating a basic frontend. But you are free to use any framework for designing the frontend according to your choice.
Create an index.html file in the initialized directory and paste the following code snippet for a basic frontend.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Marketplace</title>
</head>
<body>
<div id="createItem">
<h4>Create Item</h4>
<input
type="text"
id="txtCreateItemURI"
required
placeholder="Enter TokenURI"
/> <button id="btnCreateItem">Create Item</button>
</div> <div id="sellItem">
<h4>Sell Item</h4>
<input
type="number"
min="1"
step="1"
id="numSellItemTokenId"
placeholder="Enter TokenId"
required
/>
<input
type="number"
min="1"
step="1"
id="numSellItemPrice"
placeholder="Enter Price"
required
/> <button id="btnSellItem">Sell Item</button>
</div> <div id="buyItem">
<h4>Buy Item</h4>
<input
type="number"
min="1"
step="1"
id="numBuyItem"
placeholder="Enter SaleId"
required
/>
<input
type="number"
min="1"
step="1"
id="numBuyItemAmmount"
placeholder="Enter Ammount"
required
/> <button id="btnBuyItem">Buy Item</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="main.js"></script>
</body>
</html>
This snippet creates a frontend with the following input fields. To view the frontend locally, run parcel index.html
in the terminal and follow the issued URL.
- Create Item
This component will be used for creating/minting an NFT. It requires a string as an input which acts as TokenURI for minting an NFT. ThetokenURI
on an NFT is a unique identifier of what the token "looks" like. A URI could be an API call over HTTPS, an IPFS hash, or anything else unique. - Sell Item
This component will be used for selling an NFT. It requires two inputs, one being TokenId which is a unique non-negative integer representing an NFT, and another being Price of the NFT putting on sale, in terms of Wei(subunit of ether). - Buy Item
The last component of our app will be used for buying an NFT. It also requires two inputs, a positive integer SaleId which is unique for every sale placed, and an Amount value which must be greater than the price of that NFT.
The Frontend part wraps up here. Now we can put the Express-Protocol-SDK on work.
Express-SDK magic!
Now, we will create a main.js file in the same directory and start with importing Express-SDK and initializing it.
//Import createPandoraExpressSDK from SDK
const { createPandoraExpressSDK } = require("pandora-express");
const pandoraSDK = createPandoraExpressSDK();
The next step is to connect with the Metamask wallet for interacting with the blockchain using function-call transactions.
Make sure that you have added the Metamask extension in the browser and have enough funds for making transactions
//Connecting with Metamask wallet.
const init = async () => {
//check if metamask is present
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
await window.ethereum.enable();
console.log("Connected");
} else {
alert("Metamask not found");
}
};
We will now define a Mint function that will mint NFT using the SDK.
const mintNft = async () => {
//get current account address
const accounts = await web3.eth.getAccounts();
//Get ChainID of current account
const chainId = await web3.eth.net.getId();
//Mint NFT using SDK erc721 nft mint
await pandoraSDK.erc721.nft.mint(
web3,
chainId,
accounts[0],
itemURI.value,
[[accounts[0], 100]]
);
};
We have created a mint function using the SDK, now we can sell the NFT in the market using the Sell function of the SDK.
const sellNft = async () => {
const accounts = await web3.eth.getAccounts();
const chainId = await web3.eth.net.getId();
console.log(chainId);
await pandoraSDK.erc721.order.sellNFT(
web3,
chainId,
sellItemTokenId.value,
sellItemPrice.value,
accounts[0]
);
};
Executing this function puts an NFT on sale, anyone else can buy the NFT by providing a Price more than the sellItemPrice by using the Buy function of the SDK.
const buyNft = async () => {
const accounts = await web3.eth.getAccounts();
const chainId = await web3.eth.net.getId();
console.log(chainId);
await pandoraSDK.erc721.order.buyNFT(
web3,
chainId,
buyItemSaleId.value,
accounts[0],
buyItemAmmount.value
);
};
We will also require to fetch the input data from frontend. After adding the code for fetching data, the main.js file looks like this -
//Import createPandoraExpressSDK from SDK
const { createPandoraExpressSDK } = require("pandora-express");
const pandoraSDK = createPandoraExpressSDK();//Connecting with Metamask wallet.
const init = async () => {
//check if metamask is present
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
await window.ethereum.enable();
console.log("Connected");
} else {
alert("Metamask not found");
}
};const mintNft = async () => {
//get current account address
const accounts = await web3.eth.getAccounts();
//Get ChainID of current account
const chainId = await web3.eth.net.getId();
//Mint NFT using SDK erc721 nft mint
await pandoraSDK.erc721.nft.mint(
web3,
chainId,
accounts[0],
itemURI.value,
[[accounts[0], 100]]
);
};const sellNft = async () => {
const accounts = await web3.eth.getAccounts();
const chainId = await web3.eth.net.getId();
console.log(chainId);
await pandoraSDK.erc721.order.sellNFT(
web3,
chainId,
sellItemTokenId.value,
sellItemPrice.value,
accounts[0]
);
};const buyNft = async () => {
const accounts = await web3.eth.getAccounts();
const chainId = await web3.eth.net.getId();
console.log(chainId);
await pandoraSDK.erc721.order.buyNFT(
web3,
chainId,
buyItemSaleId.value,
accounts[0],
buyItemAmmount.value
);
};const itemURI = document.getElementById("txtCreateItemURI");const createItemButton = document.getElementById("btnCreateItem");
createItemButton.onclick = mintNft;const itemURI1 = document.getElementById("txtCreateItemURI1");
const itemURI2 = document.getElementById("txtCreateItemURI2");const createItemsButton = document.getElementById("btnCreateItemInBatch");
createItemsButton.onclick = batchMintNft;const sellItemTokenId = document.getElementById("numSellItemTokenId");
const sellItemPrice = document.getElementById("numSellItemPrice");const sellItemButton = document.getElementById("btnSellItem");
sellItemButton.onclick = sellNft;const auctionItemTokenId = document.getElementById("numAuctionItemTokenId");
const auctionItemPrice = document.getElementById("numAuctionItemPrice");
const auctionItemTime = document.getElementById("numAuctionItemTime");const auctionItemButton = document.getElementById("btnAuctionItem");
auctionItemButton.onclick = auctionNft;const buyItemSaleId = document.getElementById("numBuyItem");
const buyItemAmmount = document.getElementById("numBuyItemAmmount");
numBuyItemAmmount;const buyItemButton = document.getElementById("btnBuyItem");
buyItemButton.onclick = buyNft;init();
That’s it, folks. Now you can head to the front-end and play around with your app by minting, selling, and buying NFTs from different Metamask accounts.
Also, you can see the transaction receipts getting logged in the browser’s console and can find different events emitted with various information like tokenId, saleId, price, etc.
For exploring more functions of the Express-SDK and gaining information about them, check out the Express-Protocol-SDK docs.