thirdweb

Build an auction button in React for your dApp with TypeScript

Build an auction button in React for your dApp with TypeScript

Published on:

January 6, 2022

Create an auction button in your website

Pratham Prasoon & Raza Zaidi

What you get

This guide gives you a simple React component to create an auction and a component for a connect wallet button. Check the code at GitHub over here.

Dependencies

Quick heads up, in these examples, the thirdweb sdk is integrated with React components, but we're 'just' using javascript. You can do the same magic with another framework!

Make sure to have the dependencies installed

npm install @3rdweb/sdk @3rdweb/react @3rdweb/hooks ethers

The App.js - Connect your wallet

In your App.jsx file we can use the code from this guide for our connect wallet button. thirdweb created a component for the connect wallet button so we don't have to code it ourself. This is great so we don't have to mess around with private keys later.

Inside our app we import our component for the claim button.

App.jsx
import { ThirdwebProvider, ConnectWallet } from '@3rdweb/react'; import './App.css'; //import component for claim button import AuctionComponent from './AuctionListing'; const supportedChainIds = [1, 4, 137, 250, 43114, 80001]; const connectors = { injected: {}, magic: { }, walletconnect: {}, walletlink: { appName: "thirdweb - demo", url: "https://thirdweb.com", darkMode: false, }, }; function exampleApp() { return ( <ThirdwebProvider connectors={connectors} supportedChainIds={supportedChainIds} > <ConnectWallet /> <AuctionComponent /> /*render the claim button*/ </ThirdwebProvider> ); } export default exampleApp;

You can learn more about the walletconnect options on their official docs here and wallet link here

The AuctionListing.js - The Buy button

In your AuctionListing.js file we will write the code for the button.

Let's take it step by step, but feel free to scroll to the bottom to copy the full piece of code.

First we import all the necessary dependencies. The hooks and sdk should be familiar :).

AuctionListing.jsx
import { useCallback, useMemo, useEffect, useState } from "react"; import { ThirdwebSDK } from "@3rdweb/sdk"; import { ethers } from "ethers"; import React from "react";

In this guide we will not be passing the private keys manually. This is not considered best practice and is actually a security issue when applied on the client side. Instead we will make use of provider, which we pull when a wallet is connected via the Connect Wallet component.

The cool thing about this component, is that it's using the connect wallet component to authorise the transaction 😄.

AuctionListing.jsx
const AuctionComponent = () => { const { provider } = useWeb3();

Next up we instantiate the sdk, marketplace module and create variables with our contracts.

AuctionListing.jsx
// We won't always have a provider, and so we need to be sure to // instantiate the ThirdwebSDK with a provider *only if we have one* const sdk = useMemo( () => provider ? new ThirdwebSDK(provider.getSigner()) : new ThirdwebSDK(), [provider] ); // We should use the `useMemo` to ensure that the `market` is always // initiated with the latest `sdk` variable const market = useMemo( () => sdk.getMarketplaceModule("0xCb67A96FAd36D8c24f192B9eDaD5fF3c7A7A867f"), [sdk] ); // Declaring the nft smart contract address const nftSmartContractAddress = "0x95c78aca2c99df3E7469769C56565ECc0e8eCe95"; const currencySmartContractAddress = "0x0d5fb8942eEa62093944F3e91C6Ac4e584336741";

This part is a bit big, but it doenst make sense to split it up. First we declare some variables that will be passed through a form such as, tokend Id's, listings Id's and the amounts. Then we use the variables in our function.

A couple of notes. The createAuctionListing method takes two prices as input. buyoutPricePerToken is the variable that is used to define the buy now amount. reservePricePerToken is the variable that is used to define the minimum bid.

AuctionListing.jsx
function auctionListingTokenId(event) { setTokenId(event.target.value); } function auctionListingTokenIdOffer(event) { setTokenIdOffer(event.target.value); } function submitAuctionListing(event) { event.preventDefault(); createAuctionListing(); } const [listId, setListId] = React.useState(""); const [listIdBid, setListIdOffer] = React.useState(""); function auctionListingListId(event) { setListId(event.target.value); } function auctionListingListIdQuantity(event) { setListIdOffer(event.target.value); } function submitAuctionListingOffer(event) { event.preventDefault(); makeBid(); } //setting the minimum bid as 100th of the buyout price const tokenIdReserve = BigNumber.from(tokenIdOffer).div(100); const tokenIdReservePrice = tokenIdReserve.toString(); // We should use the `useCallback` to ensure that the `buy` // function is always initiated with the latest `market` variable const createAuctionListing = async () => { await market.createAuctionListing({ assetContractAddress: nftSmartContractAddress, buyoutPricePerToken: ethers.utils.parseUnits(tokenIdOffer, 18), currencyContractAddress: currencySmartContractAddress, startTimeInSeconds: Math.floor(Date.now() / 1000), listingDurationInSeconds: 60 * 2, tokenId: tokenId, quantity: 1, reservePricePerToken: ethers.utils.parseUnits(tokenIdReservePrice, 18), }); }, [market, tokenId, tokenIdOffer, tokenIdReservePrice]; const makeBid = async (listingId) => { await market.makeAuctionListingBid({ listingId: listId, pricePerToken: ethers.utils.parseUnits(listIdBid, 18), }); }, [listId, listIdBid, market] ;

Finally render out the forms :).

AuctionListing.jsx
return ( <div> <form onSubmit={submitAuctionListing}> <input type="text" placeholder="enter token ID to list AUCTION" onChange={auctionListingTokenId} /> <input type="text" placeholder="enter offer for the listing AUCTION" onChange={auctionListingTokenIdOffer} /> <button>Submit Token ID for Auction Listing</button> </form> <form onSubmit={submitAuctionListingOffer}> <input type="text" placeholder="enter AUCTION listing ID" onChange={auctionListingListId} /> <input type="text" placeholder="enter bid for AUCTION" onChange={auctionListingListIdQuantity} /> <button>Make a Bid</button> </form> <button style={{ padding: "10px 20px", textAlign: "center", backgroundColor: "#44014C", color: "white", }} class="btn" onClick={createAuctionListing} > Create auction listing! </button> <br /> </div> ); }; export default AuctionComponent;

The full piece of code that goes inside AuctionListing.js

AuctionListing.jsx
import { useWeb3 } from "@3rdweb/hooks"; import { useCallback, useMemo, useEffect, useState } from "react"; import { ThirdwebSDK } from "@3rdweb/sdk"; import { ethers } from "ethers"; import React from "react"; const AuctionComponent = () => { const { provider } = useWeb3(); // We won't always have a provider, and so we need to be sure to // instantiate the ThirdwebSDK with a provider *only if we have one* const sdk = useMemo( () => provider ? new ThirdwebSDK(provider.getSigner()) : new ThirdwebSDK(), [provider] ); // const sdk = useMemo(() => { // We should use the `useMemo` to ensure that the `market` is always // initiated with the latest `sdk` variable const market = useMemo( () => sdk.getMarketplaceModule("0xCb67A96FAd36D8c24f192B9eDaD5fF3c7A7A867f"), [sdk] ); // Declaring the nft smart contract address const nftSmartContractAddress = "0x95c78aca2c99df3E7469769C56565ECc0e8eCe95"; const currencySmartContractAddress = "0x0d5fb8942eEa62093944F3e91C6Ac4e584336741"; const [tokenId, setTokenId] = React.useState(""); const [tokenIdOffer, setTokenIdOffer] = React.useState(""); function auctionListingTokenId(event) { setTokenId(event.target.value); } function auctionListingTokenIdOffer(event) { setTokenIdOffer(event.target.value); } function submitAuctionListing(event) { event.preventDefault(); createAuctionListing(); } const [listId, setListId] = React.useState(""); const [listIdBid, setListIdOffer] = React.useState(""); function auctionListingListId(event) { setListId(event.target.value); } function auctionListingListIdQuantity(event) { setListIdOffer(event.target.value); } function submitAuctionListingOffer(event) { event.preventDefault(); makeBid(); } //setting the minimum bid as 100th of the buyout price const tokenIdReserve = tokenIdOffer / 1000; const tokenIdReservePrice = tokenIdReserve.toString(); // We should use the `useCallback` to ensure that the `buy` // function is always initiated with the latest `market` variable const createAuctionListing = useCallback(async () => { await market.createAuctionListing({ assetContractAddress: nftSmartContractAddress, buyoutPricePerToken: ethers.utils.parseUnits(tokenIdOffer, 18), currencyContractAddress: currencySmartContractAddress, startTimeInSeconds: Math.floor(Date.now() / 1000), listingDurationInSeconds: 60 * 2, tokenId: tokenId, quantity: 1, reservePricePerToken: ethers.utils.parseUnits(tokenIdReservePrice, 18), }); }, [market, tokenId, tokenIdOffer, tokenIdReservePrice]); const makeBid = useCallback( async (listingId) => { await market.makeAuctionListingBid({ listingId: listId, pricePerToken: ethers.utils.parseUnits(listIdBid, 18), }); }, [listId, listIdBid, market] ); return ( <div> <form onSubmit={submitAuctionListing}> <input type="text" placeholder="enter token ID to list AUCTION" onChange={auctionListingTokenId} /> <input type="text" placeholder="enter offer for the listing AUCTION" onChange={auctionListingTokenIdOffer} /> <button>Submit Token ID for Auction Listing</button> </form> <form onSubmit={submitAuctionListingOffer}> <input type="text" placeholder="enter AUCTION listing ID" onChange={auctionListingListId} /> <input type="text" placeholder="enter bid for AUCTION" onChange={auctionListingListIdQuantity} /> <button>Make a Bid</button> </form> <button style={{ padding: "10px 20px", textAlign: "center", backgroundColor: "#44014C", color: "white", }} class="btn" onClick={createAuctionListing} > Create auction listing! </button> <br /> </div> ); }; export default AuctionComponent;

That's it!

It's really that easy. If you have any questions, drop by our discord!


Ready to build your first web3 app? Get early access & add web3 features to your project today.

Pratham Prasoon & Raza Zaidi

Contents

What you get

Dependencies

The App.js - Connect your wallet

The AuctionListing.js - The Buy button

That's it!