{"id":20974332,"url":"https://github.com/thirdweb-example/marketplace","last_synced_at":"2025-05-14T12:31:49.635Z","repository":{"id":38185706,"uuid":"486387297","full_name":"thirdweb-example/marketplace","owner":"thirdweb-example","description":"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.","archived":false,"fork":false,"pushed_at":"2023-01-24T00:57:31.000Z","size":410,"stargazers_count":55,"open_issues_count":0,"forks_count":60,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-03-04T18:10:54.268Z","etag":null,"topics":["marketplace","nextjs","typescript"],"latest_commit_sha":null,"homepage":"https://marketplace.thirdweb-example.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thirdweb-example.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-27T23:59:14.000Z","updated_at":"2023-03-04T13:13:56.000Z","dependencies_parsed_at":"2023-02-13T07:15:57.593Z","dependency_job_id":null,"html_url":"https://github.com/thirdweb-example/marketplace","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fmarketplace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fmarketplace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fmarketplace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fmarketplace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thirdweb-example","download_url":"https://codeload.github.com/thirdweb-example/marketplace/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225294779,"owners_count":17451556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["marketplace","nextjs","typescript"],"created_at":"2024-11-19T04:28:14.849Z","updated_at":"2024-11-19T04:28:15.539Z","avatar_url":"https://github.com/thirdweb-example.png","language":"TypeScript","readme":"# Marketplace With Next.JS\n\n## Introduction\n\nIn this guide, you will learn how to create a marketplace like [OpenSea](https://opensea.io/) on the Goerli Ethereum test network!\n\nBy the end, we'll implement the following features:\n\n- A marketplace where we can list NFTs for **direct sale** or for **auction**.\n- Allow users to **make bids** and **buy** our NFTs.\n\n**Check out the Demo here**: https://marketplace.thirdweb-example.com\n\n## Tools\n\n- [**thirdweb Marketplace**](https://portal.thirdweb.com/contracts/marketplace): to facilitate the listing of NFTs and enable users to make buy, sell, or make offers on the NFTs on the marketplace.\n- [**thirdweb NFT Collection**](https://portal.thirdweb.com/contracts/nft-collection): to create an ERC721 NFT Collection that we can list onto the marketplace.\n- [**thirdweb React SDK**](https://docs.thirdweb.com/react): to enable users to connect and disconnect their wallets with our website, and access hooks such as [useContract](https://portal.thirdweb.com/react/react.usecontract) and [useActiveListings](https://portal.thirdweb.com/react/react.useactivelistings) to interact with the marketplace.\n- [**thirdweb TypeScript SDK**](https://docs.thirdweb.com/typescript): to connect to our marketplace smart contract, create new listings, make offers and buy listings!\n- [**Next JS Dynamic Routes**](https://nextjs.org/docs/routing/dynamic-routes): so we can have a dynamic route for each listing. eg. `listing/1` will show listing 1.\n\n## Using This Repo\n\nCreate a project using this example by running:\n\n```bash\nnpx thirdweb create --template marketplace\n```\n\n- Create your own Marketplace contract via the thirdweb dashboard. (Follow the steps in the guide below if you need extra help)!\n\n- Replace the marketplace contract address with yours in [addresses.ts](/addresses.ts) file\n\nNeed More help? Want to understand the code a bit more? Want to set the project up yourself? Follow the guide below! 👇\n\n---\n\n## Creating A Marketplace\n\nTo create a marketplace contract:\n\n- Head to the [thirdweb dashboard](https://thirdweb.com/dashboard).\n- Click **Create a new contract**.\n- Click **Setup Marketplace**.\n- Configure \u0026 Deploy!\n\n## The Thirdweb Provider\n\nThe thirdweb React provider makes it straightforward to let your users connect their wallets to your website, and it abstracts away all the boilerplate you would usually have to write.\n\nOpen `pages/_app.tsx` we wrap all of our pages in the `\u003cThirdwebProvider\u003e` component.\n\n```tsx\n\u003cThirdwebProvider activeChain=\"goerli\"\u003e\n  \u003cComponent {...pageProps} /\u003e\n\u003c/ThirdwebProvider\u003e\n```\n\n## Signing Users In With Their Wallets\n\nWe connect user's wallets to our website by using the thirdweb React SDK's [useMetamask](https://docs.thirdweb.com/react/react.usemetamask) hook.\n\n```ts\nconst connectWithMetamask = useMetamask();\n```\n\n## Displaying Listings On The Marketplace\n\nOn the [index.tsx file](./pages/index.tsx), we're displaying all of the current **active** listings on the marketplace.\n\nWe're using React's `useState` to store the listings as well as a loading flag.\n\n```ts\n// Loading Flag\nconst [loadingListings, setLoadingListings] = useState\u003cboolean\u003e(true);\n// Store Listings\nconst [listings, setListings] = useState\u003c(AuctionListing | DirectListing)[]\u003e(\n  []\n);\n```\n\nThen, we use the [useContract](https://docs.thirdweb.com/react/react.useContract) hook to connect to our smart contract via it's contract address.\n\n```ts\nconst { contract: marketplace } = useContract(\n  \"your-marketplace-address-here\",\n  \"marketplace\"\n);\n```\n\nOnce the marketplace is ready, we can use the `useActiveListings` hook to get all of the listings that are currently active (i.e. haven't expired or sold already).\n\n```tsx\nconst { data: listings, isLoading: loadingListings } =\n  useActiveListings(marketplace);\n```\n\nOnce we have the listings, we can display them to our users.\n\nWe'll leave the details of how best to display the listings up to you, but if you're looking for an example, check out the code in our [index.tsx file](./pages/index.tsx) file.\n\n## Listing Items on the marketplace\n\nWe have a page called [create.tsx](./pages/create.tsx) that lets users upload existing NFTs onto the marketplace.\n\nIf you don't have NFTs that you can list, [you can create an NFT Collection via our dashboard](https://thirdweb.com/dashboard).\n\nOnce again, we are using the `useContract` hook to connect to our marketplace smart contract via it's contract address.\n\n```ts\nconst { contract: marketplace } = useContract(\n  \"your-marketplace-address-here\",\n  \"marketplace\"\n);\n```\n\n**Create Auction Type Listing:**\n\n```ts\nasync function createAuctionListing(\n  contractAddress: string,\n  tokenId: string,\n  price: string\n) {\n  try {\n    const transaction = await marketplace?.auction.createListing({\n      assetContractAddress: contractAddress, // Contract Address of the NFT\n      buyoutPricePerToken: price, // Maximum price, the auction will end immediately if a user pays this price.\n      currencyContractAddress: NATIVE_TOKEN_ADDRESS, // NATIVE_TOKEN_ADDRESS is the cryptocurency that is native to the network. i.e. Goerli Ether\n      listingDurationInSeconds: 60 * 60 * 24 * 7, // When the auction will be closed and no longer accept bids (1 Week)\n      quantity: 1, // How many of the NFTs are being listed (useful for ERC 1155 tokens)\n      reservePricePerToken: 0, // Minimum price, users cannot bid below this amount\n      startTimestamp: new Date(), // When the listing will start (now)\n      tokenId: tokenId, // Token ID of the NFT.\n    });\n\n    return transaction;\n  } catch (error) {\n    console.error(error);\n  }\n}\n```\n\n**Create Direct Type Listing**\n\n```ts\nasync function createDirectListing(\n  contractAddress: string,\n  tokenId: string,\n  price: string\n) {\n  try {\n    const transaction = await marketplace?.direct.createListing({\n      assetContractAddress: contractAddress, // Contract Address of the NFT\n      buyoutPricePerToken: price, // Maximum price, the auction will end immediately if a user pays this price.\n      currencyContractAddress: NATIVE_TOKEN_ADDRESS, // NATIVE_TOKEN_ADDRESS is the cryptocurency that is native to the network. i.e. Goerli Ether.\n      listingDurationInSeconds: 60 * 60 * 24 * 7, // When the auction will be closed and no longer accept bids (1 Week)\n      quantity: 1, // How many of the NFTs are being listed (useful for ERC 1155 tokens)\n      startTimestamp: new Date(0), // When the listing will start (now)\n      tokenId: tokenId, // Token ID of the NFT.\n    });\n\n    return transaction;\n  } catch (error) {\n    console.error(error);\n  }\n}\n```\n\nWhen you go to list your NFT, you'll be asked for two transactions:\n\n1. Approve the marketplace to sell your NFTs while the NFT still lives in your wallet. (`setApprovalForAll`)\n2. Create the listing on the marketplace (`createListing`)\n\nIf everything worked as planned, after you approve these two transactions, you should now see the listing you just created on the home page!\n\n## Viewing A Listing\n\nOn the home page, we provide a `Link` on each listing's name to a URL that looks like: `/listing/${listing.id}`. This is using [Next JS's Dynamic Routes](https://nextjs.org/docs/routing/dynamic-routes).\n\nThis way, each NFT navigates the user to a page that shows the details of the listing when they click on it, by taking them to the `/listing/[listingId]` page.\n\nWhen the user visits the `/listing/[listingId]` page, we can fetch the information about the listing the user is looking at! E.g if the user visits `/listing/1`, we call `marketplace.getListing(1)` and load that listings information!\n\n**Fetching The Listing**\n\n```ts\nconst { contract: marketplace } = useContract(\n  \"your-marketplace-address-here\",\n  \"marketplace\"\n);\n\nuseEffect(() =\u003e {\n  if (!listingId || !marketplace) {\n    return;\n  }\n  (async () =\u003e {\n    // Use the listingId from the router.query to get the listing the user is looking at.\n    const l = await marketplace.getListing(listingId);\n\n    setLoadingListing(false);\n    setListing(l);\n  })();\n}, [listingId, marketplace]);\n```\n\nOn the `/listing/[listingId]` page, we'll want users to also be able to place bids/offers on the listing, and also buy the listing!\n\n**Creating A Bid / Offer**\n\n```ts\nasync function createBidOrOffer() {\n  try {\n    // If the listing type is a direct listing, then we can create an offer.\n    if (listing?.type === ListingType.Direct) {\n      await marketplace?.direct.makeOffer(\n        listingId, // The listingId of the listing we want to make an offer for\n        1, // Quantity = 1\n        NATIVE_TOKENS[ChainId.Goerli].wrapped.address, // Wrapped Ether address on Goerli\n        bidAmount // The offer amount the user entered\n      );\n    }\n\n    // If the listing type is an auction listing, then we can create a bid.\n    if (listing?.type === ListingType.Auction) {\n      await marketplace?.auction.makeBid(listingId, bidAmount);\n    }\n  } catch (error) {\n    console.error(error);\n  }\n}\n```\n\n**Buying the NFT**\n\n```ts\nasync function buyNft() {\n  try {\n    // Simple one-liner for buying the NFT\n    await marketplace?.buyoutListing(listingId, 1);\n  } catch (error) {\n    console.error(error);\n  }\n}\n```\n\nWe attach these functions to the `onClick` handlers of our `Buy` and `Make Offer` buttons. If you want to see how we do that, check out the code in our [[listingId].tsx file](./pages/listing/[listingId].tsx) page.\n\n**Note:** For making offers, you'll need to have an ERC20 token. For our Goerli marketplace, that means you'll need to have wrapped ETH (wETH).\n\n## Join our Discord!\n\nFor any questions, suggestions, join our discord at [https://discord.gg/thirdweb](https://discord.gg/thirdweb).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fmarketplace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthirdweb-example%2Fmarketplace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fmarketplace/lists"}