{"id":5907,"date":"2022-09-29T14:01:15","date_gmt":"2022-09-29T06:01:15","guid":{"rendered":"https:\/\/i007.vip:15443\/wordpress\/?p=5907"},"modified":"2022-09-29T14:01:15","modified_gmt":"2022-09-29T06:01:15","slug":"how-to-build-a-nft-marketplace-dapp-on-ethereum-or-optimism","status":"publish","type":"post","link":"https:\/\/i007.cc\/wordpress\/archives\/5907","title":{"rendered":"How to Build a NFT Marketplace DApp on Ethereum or Optimism"},"content":{"rendered":"<p><a href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/\">\u539f\u6587\u5730\u5740<\/a><\/p>\n<p>Written by\u00a0<a href=\"https:\/\/twitter.com\/_emjlin\">Emily Lin<\/a><\/p>\n<h2 id=\"overview\">Overview<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#overview\">\u00b6<\/a><\/h2>\n<p>Today, we&#8217;re gonna build Bored Pets Marketplace, a simple NFT marketplace using\u00a0<a href=\"https:\/\/trufflesuite.com\/\">Truffle<\/a>,\u00a0<a href=\"https:\/\/infura.io\/\">Infura<\/a>,\u00a0<a href=\"https:\/\/metamask.io\/\">MetaMask<\/a>, and\u00a0<a href=\"https:\/\/web3js.readthedocs.io\/\">Web3.js<\/a>! We&#8217;ll start off with the basics and first show you how to deploy your ethereum contracts to Truffle&#8217;s local blockchain, Ganache, and the Goerli testnet. Then, we&#8217;ll show you how to covert those contracts over to Optimism and deploy on the Optimistic Goerli testnet. Note that this tutorial will not teach you Javascript and will only briefly go over some Solidity principles.<\/p>\n<p>Our marketplace has a core set of functionality: 1. Minting and listing an NFT 2. Buying and selling an NFT 3. Viewing listed NFTs, NFTs you own, and NFTs you are selling<\/p>\n<p>This tutorial was inspired by Nader Dabit&#8217;s\u00a0<a href=\"https:\/\/dev.to\/edge-and-node\/building-scalable-full-stack-apps-on-ethereum-with-polygon-2cfb\">marketplace tutorial<\/a>. His tutorial uses\u00a0<a href=\"https:\/\/docs.ethers.io\/\">ethers.js<\/a>\u00a0and deploys to Polygon, both of which you can use Truffle with!<\/p>\n<p>The completed code for this tutorial lives\u00a0<a href=\"https:\/\/github.com\/truffle-box\/nft-marketplace-box\">here<\/a>.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#prerequisites\">\u00b6<\/a><\/h2>\n<h3 id=\"system-requirements\">System Requirements<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#system-requirements\">\u00b6<\/a><\/h3>\n<p>We will start with Truffle&#8217;s\u00a0<a href=\"https:\/\/github.com\/truffle-box\/optimism-box\">Optimism box<\/a>, scaffolding code to help get your Truffle project configured to start using Optimism asap! The\u00a0<a href=\"https:\/\/github.com\/truffle-box\/optimism-box#readme\">README<\/a>\u00a0explains the project structure in more detail.<\/p>\n<p>At the very least, you&#8217;ll need to install:<\/p>\n<ul>\n<li><a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a>, v12 or higher<\/li>\n<li><a href=\"https:\/\/trufflesuite.com\/docs\/truffle\/getting-started\/installation\/?utm_source=blog&#038;utm_medium=post&#038;utm_campaign=2022_May_truffle-blog-nft-marketplace_acquisition_content\">truffle<\/a><\/li>\n<li><a href=\"https:\/\/trufflesuite.com\/ganache\/?utm_source=blog&#038;utm_medium=post&#038;utm_campaign=2022_May_truffle-blog-nft-marketplace_acquisition_content\">ganache<\/a><\/li>\n<\/ul>\n<p>If you want to run Optimism locally, you&#8217;ll need these\u00a0<a href=\"https:\/\/community.optimism.io\/docs\/developers\/build\/dev-node\/#prerequisites\">preqrequisites<\/a>\u00a0too.<\/p>\n<h3 id=\"create-an-infura-account-and-project\">Create an Infura account and project<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#create-an-infura-account-and-project\">\u00b6<\/a><\/h3>\n<p>To connect your DApp to Ethereum, Optimism, and other networks, you&#8217;ll need an Infura account. Sign up for an account\u00a0<a href=\"https:\/\/infura.io\/register?utm_source=blog&#038;utm_medium=post&#038;utm_campaign=2022_May_truffle-blog-nft-marketplace_acquisition_content\">here<\/a>.<\/p>\n<p>Once you&#8217;re signed in, create a project! Let&#8217;s call it\u00a0<code>nft-marketplace<\/code>. Since we&#8217;re deploying to Optimism, go ahead and add the Optimistic Goerli endpoint. It&#8217;ll ask you to sign up for a free trial.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/choose_optimistic_goerli.gif\" alt=\"GIF of Adding Optimistic Goerli\" \/><\/p>\n<h3 id=\"register-for-a-metamask-wallet\">Register for a MetaMask wallet<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#register-for-a-metamask-wallet\">\u00b6<\/a><\/h3>\n<p>To interact with your DApp in the browser, you&#8217;ll need a MetaMask wallet. Sign up for an account\u00a0<a href=\"https:\/\/metamask.io\/download\/?utm_source=blog&#038;utm_medium=post&#038;utm_campaign=2022_May_truffle-blog-nft-marketplace_acquisition_content\">here<\/a>.<\/p>\n<h3 id=\"add-optimistic-goerli-to-your-wallet\">Add Optimistic Goerli to your wallet<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#add-optimistic-goerli-to-your-wallet\">\u00b6<\/a><\/h3>\n<p>Let&#8217;s add Optimistic Goerli to your list of available networks to your MetaMask wallet! To do so, open up the MetaMask extension, click on the network, and then click Add Network. Then, fill out the network properties (you can copy your Infura idf from your Infura project):<\/p>\n<ul>\n<li>Network Name: Optimistic Goerli<\/li>\n<li>New RPC URL: https:\/\/optimism-goerli.infura.io\/v3\/INFURA_PROJECT_ID<\/li>\n<li>Chain ID: 420<\/li>\n<li>Currency Symbol: ETH<\/li>\n<li>Block Explorer URL: https:\/\/blockscout.com\/optimism\/goerli\/<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/add_optimistic_goerli.gif\" alt=\"GIF of Adding Optimistic Goerli\" \/><\/p>\n<h3 id=\"get-optimistic-goerli-eth\">Get Optimistic Goerli Eth<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#get-optimistic-goerli-eth\">\u00b6<\/a><\/h3>\n<p>To use the Optimistic Goerli testnet, you&#8217;ll need some test eth. To do so, you&#8217;ll need to:<\/p>\n<p>1) Get some Goerli Eth. You can use this\u00a0<a href=\"https:\/\/faucet.paradigm.xyz\/\">faucet<\/a>\u00a02) Optimism&#8217;s gateway still doesn&#8217;t support Goerli, but if you transfer Goerli ETH to\u00a0<a href=\"https:\/\/goerli.etherscan.io\/address\/0x636Af16bf2f682dD3109e60102b8E1A089FedAa8\">0x636Af16bf2f682dD3109e60102b8E1A089FedAa8<\/a>, you will get it on Optimistic Goerli.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/get_optimistic_goerli_eth.gif\" alt=\"GIF of Getting Optimistic Goerli Eth\" \/><\/p>\n<h3 id=\"vscode\">VSCode<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#vscode\">\u00b6<\/a><\/h3>\n<p>Feel free to use whatever IDE you want, but we highly recommend using VSCode! You can run through most of this tutorial using the Truffle extension to create, build, and deploy your smart contracts, all without using the CLI! You can read more about it\u00a0<a href=\"https:\/\/trufflesuite.com\/blog\/build-on-web3-with-truffle-vs-code-extension\/\">here<\/a>.<\/p>\n<h2 id=\"set-up-your-project\">Set Up Your Project<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#set-up-your-project\">\u00b6<\/a><\/h2>\n<h3 id=\"unbox-optimism\">Unbox Optimism<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#unbox-optimism\">\u00b6<\/a><\/h3>\n<p>To get started, we&#8217;ll start off by unboxing Truffle&#8217;s Optimism box. You can do this by calling\u00a0<code>truffle unbox optimism [FOLDER_NAME]<\/code>\u00a0or through the VSCode extension command palette! Go ahead and install the requisite packages as well.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_1\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_1 > code\"><\/button><code>truffle unbox optimism nft-marketplace\r\n<span class=\"nb\">cd<\/span> nft-marketplace\r\nnpm install\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"create-your-client-folders\">Create your client folders<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#create-your-client-folders\">\u00b6<\/a><\/h3>\n<p>We&#8217;ll also be using\u00a0<a href=\"https:\/\/nextjs.org\/\">Next.js<\/a>\u00a0and\u00a0<a href=\"https:\/\/tailwindcss.com\/\">Tailwind CSS<\/a>\u00a0for our client. So, to get that set up, we&#8217;ll use Next&#8217;s\u00a0<a href=\"https:\/\/nextjs.org\/docs\/api-reference\/create-next-app\">create-next-app<\/a>\u00a0utility.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_2\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_2 > code\"><\/button><code>npx create-next-app@latest client\r\n<\/code><\/pre>\n<\/div>\n<p>Then, we&#8217;ll download the Tailwind dependencies and populate its config.<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_3\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_3 > code\"><\/button><code><span class=\"nb\">cd<\/span> client\r\nnpm install -D tailwindcss@latest postcss@latest autoprefixer@latest\r\nnpx tailwindcss init -p\r\n<\/code><\/pre>\n<\/div>\n<p>Edit\u00a0<code>tailwind.config.js<\/code><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_4\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_4 > code\"><\/button><code><span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">content<\/span><span class=\"o\">:<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"s2\">\".\/pages\/**\/*.{js,ts,jsx,tsx}\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"s2\">\".\/components\/**\/*.{js,ts,jsx,tsx}\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"p\">],<\/span>\r\n  <span class=\"nx\">theme<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nx\">extend<\/span><span class=\"o\">:<\/span> <span class=\"p\">{},<\/span>\r\n  <span class=\"p\">},<\/span>\r\n  <span class=\"nx\">plugins<\/span><span class=\"o\">:<\/span> <span class=\"p\">[],<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>And replace the code from\u00a0<code>styles\/global.css<\/code><\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_5\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_5 > code\"><\/button><code><span class=\"p\">@<\/span><span class=\"k\">tailwind<\/span> <span class=\"nt\">base<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">@<\/span><span class=\"k\">tailwind<\/span> <span class=\"nt\">components<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">@<\/span><span class=\"k\">tailwind<\/span> <span class=\"nt\">utilities<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"edit-the-truffle-config-files\">Edit the Truffle config files<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#edit-the-truffle-config-files\">\u00b6<\/a><\/h3>\n<p>Since we&#8217;ll be referencing your compiled contracts in the client, let&#8217;s change\u00a0<code>contracts_build_directory<\/code>\u00a0in the Truffle config files:<\/p>\n<ul>\n<li>In\u00a0<code>truffle-config.js<\/code>, change the value to\u00a0<code>'.\/client\/contracts\/ethereum-contracts'<\/code>.<\/li>\n<li>In\u00a0<code>truffle-config.ovm.js<\/code>, change the value to\u00a0<code>'.\/client\/contracts\/optimism-contracts'<\/code>.<\/li>\n<\/ul>\n<p>Your top level folder structure should look like this!<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_6\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_6 > code\"><\/button><code>nft-marketplace\r\n\u251c\u2500\u2500 LICENSE\r\n\u251c\u2500\u2500 README.md\r\n\u251c\u2500\u2500 box-img-lg.png\r\n\u251c\u2500\u2500 box-img-sm.png\r\n\u251c\u2500\u2500 client\r\n\u251c\u2500\u2500 contracts\r\n\u251c\u2500\u2500 migrations\r\n\u251c\u2500\u2500 node_modules\r\n\u251c\u2500\u2500 package-lock.json\r\n\u251c\u2500\u2500 package.json\r\n\u251c\u2500\u2500 <span class=\"nb\">test<\/span>\r\n\u251c\u2500\u2500 truffle-config.js\r\n\u2514\u2500\u2500 truffle-config.ovm.js\r\n<\/code><\/pre>\n<\/div>\n<h2 id=\"build-the-nft-smart-contract\">Build the NFT Smart Contract<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#build-the-nft-smart-contract\">\u00b6<\/a><\/h2>\n<p>Since we are first showing you how to deploy on Ethereum, we&#8217;ll edit the\u00a0<code>SimpleStorage.sol<\/code>\u00a0contract under\u00a0<code>contracts\/ethereum<\/code>. Change the file name and contract name to\u00a0<code>BoredPetsNFT.sol<\/code>.<\/p>\n<p>We&#8217;ll need to install\u00a0<a href=\"https:\/\/www.openzeppelin.com\/\">OpenZeppelin<\/a>. First, switch back into your\u00a0<code>nft-marketplace<\/code>\u00a0directory<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_7\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_7 > code\"><\/button><code><span class=\"nb\">cd<\/span> ..\r\nnpm install @openzeppelin\/contracts\r\n<\/code><\/pre>\n<\/div>\n<p>The smart contract looks like this:<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_8\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_8 > code\"><\/button><code><span class=\"c1\">\/\/ SPDX-License-Identifier: MIT<\/span>\r\n<span class=\"n\">pragma<\/span> <span class=\"n\">solidity<\/span> <span class=\"o\">^<\/span><span class=\"mf\">0.8.13<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"kn\">import<\/span> <span class=\"err\">\"@<\/span><span class=\"nn\">openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">token<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n<span class=\"s\">import \"<\/span><span class=\"nd\">@openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">token<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721<\/span><span class=\"o\">\/<\/span><span class=\"n\">extensions<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721URIStorage<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n<span class=\"s\">import \"<\/span><span class=\"nd\">@openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">utils<\/span><span class=\"o\">\/<\/span><span class=\"n\">Counters<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n\r\n<span class=\"s\">contract BoredPetsNFT is ERC721URIStorage {<\/span>\r\n<span class=\"s\">  using Counters for Counters.Counter;<\/span>\r\n<span class=\"s\">  Counters.Counter private _tokenIds;<\/span>\r\n<span class=\"s\">  address marketplaceContract;<\/span>\r\n<span class=\"s\">  event NFTMinted(uint256);<\/span>\r\n\r\n<span class=\"s\">  constructor(address _marketplaceContract) ERC721(\"<\/span><span class=\"n\">Bored<\/span> <span class=\"n\">Pets<\/span> <span class=\"n\">Yacht<\/span> <span class=\"n\">Club<\/span><span class=\"s\">\", \"<\/span><span class=\"n\">BPYC<\/span><span class=\"s\">\") {<\/span>\r\n<span class=\"s\">    marketplaceContract = _marketplaceContract;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  function mint(string memory _tokenURI) public {<\/span>\r\n<span class=\"s\">    _tokenIds.increment();<\/span>\r\n<span class=\"s\">    uint256 newTokenId = _tokenIds.current();<\/span>\r\n<span class=\"s\">    _safeMint(msg.sender, newTokenId);<\/span>\r\n<span class=\"s\">    _setTokenURI(newTokenId, _tokenURI);<\/span>\r\n<span class=\"s\">    setApprovalForAll(marketplaceContract, true);<\/span>\r\n<span class=\"s\">    emit NFTMinted(newTokenId);<\/span>\r\n<span class=\"s\">  }<\/span>\r\n<span class=\"s\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>Creating the NFT smart contract is short and sweet! Let&#8217;s first take a look at the imports:<\/p>\n<p>\u00a0<\/p>\n<ul>\n<li>@openzeppelin\/contracts\/token\/ERC721\/ERC721.sol<\/li>\n<\/ul>\n<p>To be a valid NFT,\u00a0<code>BoredPetNFT<\/code>\u00a0implements the\u00a0<a href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-721\">ERC721 standard<\/a>\u00a0by inheriting the implementation of\u00a0<code>ERC721URIStorage.sol<\/code><\/p>\n<ul>\n<li>@openzeppelin\/contracts\/token\/ERC721\/extensions\/ERC721URIStorage.sol<\/li>\n<\/ul>\n<p>This implementation of\u00a0<code>ERC721<\/code>\u00a0is used so that we store the tokenURIs on chain in\u00a0<code>storage<\/code>, which is what allows us to store the metadata we upload to IPFS off-chain.<\/p>\n<ul>\n<li>@openzeppelin\/contracts\/utils\/Counters.sol<\/li>\n<\/ul>\n<p>We use a counter to track the total number of NFTs and assign a unique token id to each NFT.<\/p>\n<p>At the top we define a few variables:<\/p>\n<ul>\n<li><code>address marketplaceContract<\/code>\u00a0is the address of the Marketplace contract we&#8217;ll be writing in the next section.<\/li>\n<li><code>event NFTMinted<\/code>\u00a0will be emitted every time a NFT is minted. When an event is emitted in solidity, the parameters are stored in the transaction&#8217;s log. We will need the tokenId later when we build out the web app.<\/li>\n<\/ul>\n<p>And finally, we only need to define the\u00a0<code>mint<\/code>\u00a0function! It only has one parameter: &#8211;\u00a0<code>string memory _tokenURI<\/code>\u00a0points to the JSON metdata on IPFS that stores the NFT&#8217;s metadata (i.e., image, name, description)<\/p>\n<p><code>mint<\/code>\u00a0is relatively straightforward &#8211; it mints an NFT with an increasing, unique token Id. Of note, however, is\u00a0<code>setApprovalForAll<\/code>. This is important because our Marketplace contract will need approver access to transfer ownership of the NFT between various addresses.<\/p>\n<h2 id=\"build-the-marketplace-contract\">Build the Marketplace Contract<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#build-the-marketplace-contract\">\u00b6<\/a><\/h2>\n<p>Now, let&#8217;s add a new contract\u00a0<code>Marketplace.sol<\/code>\u00a0under\u00a0<code>contracts\/ethereum<\/code>, which will store all the marketplace functionality. This&#8217;ll be what it ends up like:<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_9\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_9 > code\"><\/button><code><span class=\"c1\">\/\/ SPDX-License-Identifier: MIT<\/span>\r\n<span class=\"n\">pragma<\/span> <span class=\"n\">solidity<\/span> <span class=\"o\">^<\/span><span class=\"mf\">0.8.13<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"kn\">import<\/span> <span class=\"err\">\"@<\/span><span class=\"nn\">openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">utils<\/span><span class=\"o\">\/<\/span><span class=\"n\">Counters<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n<span class=\"s\">import \"<\/span><span class=\"nd\">@openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">token<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721<\/span><span class=\"o\">\/<\/span><span class=\"n\">ERC721<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n<span class=\"s\">import \"<\/span><span class=\"nd\">@openzeppelin<\/span><span class=\"o\">\/<\/span><span class=\"n\">contracts<\/span><span class=\"o\">\/<\/span><span class=\"n\">security<\/span><span class=\"o\">\/<\/span><span class=\"n\">ReentrancyGuard<\/span><span class=\"p\">.<\/span><span class=\"na\">sol<\/span><span class=\"s\">\";<\/span>\r\n\r\n<span class=\"s\">contract Marketplace is ReentrancyGuard {<\/span>\r\n<span class=\"s\">  using Counters for Counters.Counter;<\/span>\r\n<span class=\"s\">  Counters.Counter private _nftsSold;<\/span>\r\n<span class=\"s\">  Counters.Counter private _nftCount;<\/span>\r\n<span class=\"s\">  uint256 public LISTING_FEE = 0.0001 ether;<\/span>\r\n<span class=\"s\">  address payable private _marketOwner;<\/span>\r\n<span class=\"s\">  mapping(uint256 => NFT) private _idToNFT;<\/span>\r\n<span class=\"s\">  struct NFT {<\/span>\r\n<span class=\"s\">    address nftContract;<\/span>\r\n<span class=\"s\">    uint256 tokenId;<\/span>\r\n<span class=\"s\">    address payable seller;<\/span>\r\n<span class=\"s\">    address payable owner;<\/span>\r\n<span class=\"s\">    uint256 price;<\/span>\r\n<span class=\"s\">    bool listed;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n<span class=\"s\">  event NFTListed(<\/span>\r\n<span class=\"s\">    address nftContract,<\/span>\r\n<span class=\"s\">    uint256 tokenId,<\/span>\r\n<span class=\"s\">    address seller,<\/span>\r\n<span class=\"s\">    address owner,<\/span>\r\n<span class=\"s\">    uint256 price<\/span>\r\n<span class=\"s\">  );<\/span>\r\n<span class=\"s\">  event NFTSold(<\/span>\r\n<span class=\"s\">    address nftContract,<\/span>\r\n<span class=\"s\">    uint256 tokenId,<\/span>\r\n<span class=\"s\">    address seller,<\/span>\r\n<span class=\"s\">    address owner,<\/span>\r\n<span class=\"s\">    uint256 price<\/span>\r\n<span class=\"s\">  );<\/span>\r\n\r\n<span class=\"s\">  constructor() {<\/span>\r\n<span class=\"s\">    _marketOwner = payable(msg.sender);<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  \/\/ List the NFT on the marketplace<\/span>\r\n<span class=\"s\">  function listNft(address _nftContract, uint256 _tokenId, uint256 _price) public payable nonReentrant {<\/span>\r\n<span class=\"s\">    require(_price > 0, \"<\/span><span class=\"n\">Price<\/span> <span class=\"n\">must<\/span> <span class=\"n\">be<\/span> <span class=\"n\">at<\/span> <span class=\"n\">least<\/span> <span class=\"mi\">1<\/span> <span class=\"n\">wei<\/span><span class=\"s\">\");<\/span>\r\n<span class=\"s\">    require(msg.value == LISTING_FEE, \"<\/span><span class=\"n\">Not<\/span> <span class=\"n\">enough<\/span> <span class=\"n\">ether<\/span> <span class=\"k\">for<\/span> <span class=\"n\">listing<\/span> <span class=\"n\">fee<\/span><span class=\"s\">\");<\/span>\r\n\r\n<span class=\"s\">    IERC721(_nftContract).transferFrom(msg.sender, address(this), _tokenId);<\/span>\r\n\r\n<span class=\"s\">    _nftCount.increment();<\/span>\r\n\r\n<span class=\"s\">    _idToNFT[_tokenId] = NFT(<\/span>\r\n<span class=\"s\">      _nftContract,<\/span>\r\n<span class=\"s\">      _tokenId, <\/span>\r\n<span class=\"s\">      payable(msg.sender),<\/span>\r\n<span class=\"s\">      payable(address(this)),<\/span>\r\n<span class=\"s\">      _price,<\/span>\r\n<span class=\"s\">      true<\/span>\r\n<span class=\"s\">    );<\/span>\r\n\r\n<span class=\"s\">    emit NFTListed(_nftContract, _tokenId, msg.sender, address(this), _price);<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  \/\/ Buy an NFT<\/span>\r\n<span class=\"s\">  function buyNft(address _nftContract, uint256 _tokenId) public payable nonReentrant {<\/span>\r\n<span class=\"s\">    NFT storage nft = _idToNFT[_tokenId];<\/span>\r\n<span class=\"s\">    require(msg.value >= nft.price, \"<\/span><span class=\"n\">Not<\/span> <span class=\"n\">enough<\/span> <span class=\"n\">ether<\/span> <span class=\"n\">to<\/span> <span class=\"n\">cover<\/span> <span class=\"n\">asking<\/span> <span class=\"n\">price<\/span><span class=\"s\">\");<\/span>\r\n\r\n<span class=\"s\">    address payable buyer = payable(msg.sender);<\/span>\r\n<span class=\"s\">    payable(nft.seller).transfer(msg.value);<\/span>\r\n<span class=\"s\">    IERC721(_nftContract).transferFrom(address(this), buyer, nft.tokenId);<\/span>\r\n<span class=\"s\">    _marketOwner.transfer(LISTING_FEE);<\/span>\r\n<span class=\"s\">    nft.owner = buyer;<\/span>\r\n<span class=\"s\">    nft.listed = false;<\/span>\r\n\r\n<span class=\"s\">    _nftsSold.increment();<\/span>\r\n<span class=\"s\">    emit NFTSold(_nftContract, nft.tokenId, nft.seller, buyer, msg.value);<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  \/\/ Resell an NFT purchased from the marketplace<\/span>\r\n<span class=\"s\">  function resellNft(address _nftContract, uint256 _tokenId, uint256 _price) public payable nonReentrant {<\/span>\r\n<span class=\"s\">    require(_price > 0, \"<\/span><span class=\"n\">Price<\/span> <span class=\"n\">must<\/span> <span class=\"n\">be<\/span> <span class=\"n\">at<\/span> <span class=\"n\">least<\/span> <span class=\"mi\">1<\/span> <span class=\"n\">wei<\/span><span class=\"s\">\");<\/span>\r\n<span class=\"s\">    require(msg.value == LISTING_FEE, \"<\/span><span class=\"n\">Not<\/span> <span class=\"n\">enough<\/span> <span class=\"n\">ether<\/span> <span class=\"k\">for<\/span> <span class=\"n\">listing<\/span> <span class=\"n\">fee<\/span><span class=\"s\">\");<\/span>\r\n\r\n<span class=\"s\">    IERC721(_nftContract).transferFrom(msg.sender, address(this), _tokenId);<\/span>\r\n\r\n<span class=\"s\">    NFT storage nft = _idToNFT[_tokenId];<\/span>\r\n<span class=\"s\">    nft.seller = payable(msg.sender);<\/span>\r\n<span class=\"s\">    nft.owner = payable(address(this));<\/span>\r\n<span class=\"s\">    nft.listed = true;<\/span>\r\n<span class=\"s\">    nft.price = _price;<\/span>\r\n\r\n<span class=\"s\">    _nftsSold.decrement();<\/span>\r\n<span class=\"s\">    emit NFTListed(_nftContract, _tokenId, msg.sender, address(this), _price);<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  function getListingFee() public view returns (uint256) {<\/span>\r\n<span class=\"s\">    return LISTING_FEE;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  function getListedNfts() public view returns (NFT[] memory) {<\/span>\r\n<span class=\"s\">    uint256 nftCount = _nftCount.current();<\/span>\r\n<span class=\"s\">    uint256 unsoldNftsCount = nftCount - _nftsSold.current();<\/span>\r\n\r\n<span class=\"s\">    NFT[] memory nfts = new NFT[](unsoldNftsCount);<\/span>\r\n<span class=\"s\">    uint nftsIndex = 0;<\/span>\r\n<span class=\"s\">    for (uint i = 0; i < nftCount; i++) {<\/span>\r\n<span class=\"s\">      if (_idToNFT[i + 1].listed) {<\/span>\r\n<span class=\"s\">        nfts[nftsIndex] = _idToNFT[i + 1];<\/span>\r\n<span class=\"s\">        nftsIndex++;<\/span>\r\n<span class=\"s\">      }<\/span>\r\n<span class=\"s\">    }<\/span>\r\n<span class=\"s\">    return nfts;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  function getMyNfts() public view returns (NFT[] memory) {<\/span>\r\n<span class=\"s\">    uint nftCount = _nftCount.current();<\/span>\r\n<span class=\"s\">    uint myNftCount = 0;<\/span>\r\n<span class=\"s\">    for (uint i = 0; i < nftCount; i++) {<\/span>\r\n<span class=\"s\">      if (_idToNFT[i + 1].owner == msg.sender) {<\/span>\r\n<span class=\"s\">        myNftCount++;<\/span>\r\n<span class=\"s\">      }<\/span>\r\n<span class=\"s\">    }<\/span>\r\n\r\n<span class=\"s\">    NFT[] memory nfts = new NFT[](myNftCount);<\/span>\r\n<span class=\"s\">    uint nftsIndex = 0;<\/span>\r\n<span class=\"s\">    for (uint i = 0; i < nftCount; i++) {<\/span>\r\n<span class=\"s\">      if (_idToNFT[i + 1].owner == msg.sender) {<\/span>\r\n<span class=\"s\">        nfts[nftsIndex] = _idToNFT[i + 1];<\/span>\r\n<span class=\"s\">        nftsIndex++;<\/span>\r\n<span class=\"s\">      }<\/span>\r\n<span class=\"s\">    }<\/span>\r\n<span class=\"s\">    return nfts;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n\r\n<span class=\"s\">  function getMyListedNfts() public view returns (NFT[] memory) {<\/span>\r\n<span class=\"s\">    uint nftCount = _nftCount.current();<\/span>\r\n<span class=\"s\">    uint myListedNftCount = 0;<\/span>\r\n<span class=\"s\">    for (uint i = 0; i < nftCount; i++) {<\/span>\r\n<span class=\"s\">      if (_idToNFT[i + 1].seller == msg.sender && _idToNFT[i + 1].listed) {<\/span>\r\n<span class=\"s\">        myListedNftCount++;<\/span>\r\n<span class=\"s\">      }<\/span>\r\n<span class=\"s\">    }<\/span>\r\n\r\n<span class=\"s\">    NFT[] memory nfts = new NFT[](myListedNftCount);<\/span>\r\n<span class=\"s\">    uint nftsIndex = 0;<\/span>\r\n<span class=\"s\">    for (uint i = 0; i < nftCount; i++) {<\/span>\r\n<span class=\"s\">      if (_idToNFT[i + 1].seller == msg.sender && _idToNFT[i + 1].listed) {<\/span>\r\n<span class=\"s\">        nfts[nftsIndex] = _idToNFT[i + 1];<\/span>\r\n<span class=\"s\">        nftsIndex++;<\/span>\r\n<span class=\"s\">      }<\/span>\r\n<span class=\"s\">    }<\/span>\r\n<span class=\"s\">    return nfts;<\/span>\r\n<span class=\"s\">  }<\/span>\r\n<span class=\"s\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>There&#8217;s a lot to unpack here! You might notice that the Marketplace contract inherits\u00a0<code>ReentrancyGuard<\/code>. We do this so that we can defend against reentrancy attacks. You can read more about them\u00a0<a href=\"https:\/\/medium.com\/coinmonks\/protect-your-solidity-smart-contracts-from-reentrancy-attacks-9972c3af7c21\">here<\/a>.<\/p>\n<p>\u00a0<\/p>\n<p>First, let&#8217;s dive into the contract variables: &#8211;\u00a0<code>Counters.Counter private _nftsSold<\/code>\u00a0increments when a NFT is sold and decremented when a NFT is relisted. &#8211;\u00a0<code>Counters.Counter private _nftCount<\/code>\u00a0tracks how many NFTs have been listed. &#8211;\u00a0<code>uint256 public LISTING_FEE<\/code>\u00a0is taken from the seller and transferred to the marketplace contract owner whenever an NFT is sold. &#8211;\u00a0<code>address payable private _marketOwner<\/code>\u00a0stores the Marketplace contract owner, so that we know who to pay the listing fee to. &#8211;\u00a0<code>mapping(uint256 => NFT) private _idToNFT<\/code>\u00a0associates the unique tokenId to a the NFT struct. &#8211;\u00a0<code>struct NFT<\/code>\u00a0stores relevant information for an NFT listed in the marketplace. &#8211;\u00a0<code>event NFTListed<\/code>\u00a0is emitted every time a NFT is listed. &#8211;\u00a0<code>event NFTSold<\/code>\u00a0is emitted every time a NFT is sold.<\/p>\n<p>Next, we&#8217;ll go over the functions that will alter state: &#8211;\u00a0<code>listNft<\/code>\u00a0is called when a user first mints and lists their NFT. It transfers ownership from the user over to the Marketplace contract. &#8211;\u00a0<code>resellNft<\/code>\u00a0allows users to sell an NFT that they purchase on the marketplace. &#8211;\u00a0<code>buyNft<\/code>\u00a0is called when a user buys an NFT. The buyer becomes the new owner of the NFT, the token is transferred from the buyer to the seller, and the listing fee is given to the marketplace owner.<\/p>\n<p>Finally, the query functions are relatively straightforward:<\/p>\n<ul>\n<li><code>getListingFee<\/code>\u00a0returns the listing fee. This is entirely optional. When you deploy a smart contract, a LISTING_FEE() function is actually created for you, but we created a getter function for code cleanliness.<\/li>\n<li><code>getListedNfts<\/code>\u00a0retrieves the NFTs that are currently listed for sale.<\/li>\n<li><code>getMyNfts<\/code>\u00a0retrieves the NFTs the user has bought.<\/li>\n<li><code>getMyListedNfts<\/code>\u00a0retrieves the NFTs the user has listed for sale.<\/li>\n<\/ul>\n<h2 id=\"deploy-the-smart-contracts-locally\">Deploy the Smart Contracts Locally<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-the-smart-contracts-locally\">\u00b6<\/a><\/h2>\n<p>In order to deploy our smart contracts, we&#8217;ll need to modify\u00a0<code>migrations\/1_deploy_contracts.js<\/code>. Because\u00a0<code>BoredPetsNFT<\/code>\u00a0requires the\u00a0<code>Marketplace<\/code>\u00a0contract address, order matters here! Truffle allows you to deploy contracts in order using\u00a0<code>Promise<\/code>\u00a0or\u00a0<code>await<\/code>\/<code>async<\/code>. You can read more about it\u00a0<a href=\"https:\/\/trufflesuite.com\/docs\/truffle\/getting-started\/running-migrations\/#deployer\">here<\/a>. (Note that previously, Truffle also required a separate\u00a0<code>Migrations.sol<\/code>\u00a0contract, but that is no longer the case!)<\/p>\n<p>Your deployment file should look like this:<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_10\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_10 > code\"><\/button><code><span class=\"kd\">var<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">artifacts<\/span><span class=\"p\">.<\/span><span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"BoredPetsNFT\"<\/span><span class=\"p\">);<\/span>\r\n<span class=\"kd\">var<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">artifacts<\/span><span class=\"p\">.<\/span><span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Marketplace\"<\/span><span class=\"p\">);<\/span>\r\n\r\n<span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">deployer<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">await<\/span> <span class=\"nx\">deployer<\/span><span class=\"p\">.<\/span><span class=\"nx\">deploy<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"nx\">marketplace<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">deployed<\/span><span class=\"p\">();<\/span>\r\n  <span class=\"k\">await<\/span> <span class=\"nx\">deployer<\/span><span class=\"p\">.<\/span><span class=\"nx\">deploy<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">,<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>There are a variety of ways to get your local Ganache instance up: through the VS Code extension, Ganache CLI, and the Ganche graphical user interface. Each has its own advantages, and you can check out v7&#8217;s coolest features\u00a0<a href=\"https:\/\/trufflesuite.com\/blog\/introducing-ganache-7\/\">here<\/a>.<\/p>\n<p>\u00a0<\/p>\n<p>In this example, we&#8217;ll be using the GUI. Open it up, create a workspace, and hit save!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/open_ganache_workspace.gif\" alt=\"GIF of creating Ganache workspace\" \/><\/p>\n<p>This creates a running Ganache instance at HTTP:\/\/127.0.0.1:7545. Now, just run\u00a0<code>truffle migrate --network development<\/code>\u00a0in the CLI from the\u00a0<code>nft-marketplace<\/code>\u00a0folder. This will compile and deploy your contracts. You should see output similar to this:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_11\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_11 > code\"><\/button><code>Compiling your contracts...\r\n<span class=\"o\">===========================<\/span>\r\n> Compiling .\/contracts\/ethereum\/BoredPetsNFT.sol.sol\r\n> Compiling .\/contracts\/ethereum\/Marketplace.sol\r\n> Compiling @openzeppelin\/contracts\/security\/ReentrancyGuard.sol\r\n> Compiling @openzeppelin\/contracts\/token\/ERC721\/ERC721.sol\r\n> Compiling @openzeppelin\/contracts\/token\/ERC721\/IERC721.sol\r\n> Compiling @openzeppelin\/contracts\/token\/ERC721\/IERC721Receiver.sol\r\n> Compiling @openzeppelin\/contracts\/token\/ERC721\/extensions\/ERC721URIStorage.sol\r\n> Compiling @openzeppelin\/contracts\/token\/ERC721\/extensions\/IERC721Metadata.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/Address.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/Context.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/Counters.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/Strings.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/introspection\/ERC165.sol\r\n> Compiling @openzeppelin\/contracts\/utils\/introspection\/IERC165.sol\r\n> Artifacts written to \/Users\/emilylin\/truffle\/nft-marketplace\/client\/contracts\/ethereum-contracts\r\n> Compiled successfully using:\r\n   - solc: <span class=\"m\">0<\/span>.8.13+commit.abaa5c0e.Emscripten.clang\r\n\r\n\r\nStarting migrations...\r\n<span class=\"o\">======================<\/span>\r\n> Network name:    <span class=\"s1\">'development'<\/span>\r\n> Network id:      <span class=\"m\">5777<\/span>\r\n> Block gas limit: <span class=\"m\">6721975<\/span> <span class=\"o\">(<\/span>0x6691b7<span class=\"o\">)<\/span>\r\n\r\n\r\n1_deploy_contracts.js\r\n<span class=\"o\">=====================<\/span>\r\n\r\n   Deploying <span class=\"s1\">'Marketplace'<\/span>\r\n   -----------------------\r\n   > transaction hash:    0xca3f5fcc301c700bdfd7bfb58c853e39085335ed0ef249bf57334ad856848383\r\n   > Blocks: <span class=\"m\">0<\/span>            Seconds: <span class=\"m\">0<\/span>\r\n   > contract address:    0x6F1A6D8a5414d1B1E67b69D69D5206498447aceE\r\n   > block number:        <span class=\"m\">1<\/span>\r\n   > block timestamp:     <span class=\"m\">1652487728<\/span>\r\n   > account:             0x24D126143330E7f76753e13FAE39a844cbcEe829\r\n   > balance:             <span class=\"m\">99<\/span>.96632092\r\n   > gas used:            <span class=\"m\">1683954<\/span> <span class=\"o\">(<\/span>0x19b1f2<span class=\"o\">)<\/span>\r\n   > gas price:           <span class=\"m\">20<\/span> gwei\r\n   > value sent:          <span class=\"m\">0<\/span> ETH\r\n   > total cost:          <span class=\"m\">0<\/span>.03367908 ETH\r\n\r\n\r\n   Deploying <span class=\"s1\">'BoredPetsNFT'<\/span>\r\n   ---------------------------\r\n   > transaction hash:    0x077ab3a709addd41229de58f3bb6ad913a5c4646cd5df39272a9db6ad3a04f05\r\n   > Blocks: <span class=\"m\">0<\/span>            Seconds: <span class=\"m\">0<\/span>\r\n   > contract address:    0x2935aBf19126137D47bCa1612Dc4900815A15E92\r\n   > block number:        <span class=\"m\">2<\/span>\r\n   > block timestamp:     <span class=\"m\">1652487729<\/span>\r\n   > account:             0x24D126143330E7f76753e13FAE39a844cbcEe829\r\n   > balance:             <span class=\"m\">99<\/span>.91495866\r\n   > gas used:            <span class=\"m\">2568113<\/span> <span class=\"o\">(<\/span>0x272fb1<span class=\"o\">)<\/span>\r\n   > gas price:           <span class=\"m\">20<\/span> gwei\r\n   > value sent:          <span class=\"m\">0<\/span> ETH\r\n   > total cost:          <span class=\"m\">0<\/span>.05136226 ETH\r\n\r\n   > Saving artifacts\r\n   -------------------------------------\r\n   > Total cost:          <span class=\"m\">0<\/span>.08504134 ETH\r\n\r\n<span class=\"nv\">Summary<\/span>\r\n<span class=\"o\">=======<\/span>\r\n> Total deployments:   <span class=\"m\">2<\/span>\r\n> Final cost:          <span class=\"m\">0<\/span>.08504134 ETH\r\n<\/code><\/pre>\n<\/div>\n<p>You should be able to find your compiled contracts under\u00a0<code>.\/client\/contracts\/ethereum-contracts<\/code><\/p>\n<h2 id=\"test-your-smart-contracts\">Test Your Smart Contracts<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#test-your-smart-contracts\">\u00b6<\/a><\/h2>\n<p>In order to quickly test our smart contracts, we&#8217;ll take advantage of\u00a0<code>truffle exec<\/code>\u00a0to run scripts to automate common tasks. Let&#8217;s write a script that will execute all of our different functions. First, create a new file under a new\u00a0<code>scripts<\/code>\u00a0folder called\u00a0<code>run.js<\/code>.<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_12\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_12 > code\"><\/button><code><span class=\"kd\">var<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">artifacts<\/span><span class=\"p\">.<\/span><span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"BoredPetsNFT\"<\/span><span class=\"p\">);<\/span>\r\n<span class=\"kd\">var<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">artifacts<\/span><span class=\"p\">.<\/span><span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Marketplace\"<\/span><span class=\"p\">);<\/span>\r\n\r\n<span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">logNftLists<\/span><span class=\"p\">(<\/span><span class=\"nx\">marketplace<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">listedNfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">getListedNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">accountAddress<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">'FIRST_ACCOUNT_ADDRESS'<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">myNfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">getMyNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">call<\/span><span class=\"p\">({<\/span><span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accountAddress<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">myListedNfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">getMyListedNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">call<\/span><span class=\"p\">({<\/span><span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accountAddress<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`listedNfts: <\/span><span class=\"si\">${<\/span><span class=\"nx\">listedNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`myNfts: <\/span><span class=\"si\">${<\/span><span class=\"nx\">myNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`myListedNfts <\/span><span class=\"si\">${<\/span><span class=\"nx\">myListedNfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"si\">}<\/span><span class=\"sb\">n`<\/span><span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">main<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async<\/span> <span class=\"p\">(<\/span><span class=\"nx\">cb<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">boredPets<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">deployed<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketplace<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">deployed<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'MINT AND LIST 3 NFTs'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">getListingFee<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">.<\/span><span class=\"nx\">toString<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">txn1<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">mint<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"URI1\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">tokenId1<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">txn1<\/span><span class=\"p\">.<\/span><span class=\"nx\">logs<\/span><span class=\"p\">[<\/span><span class=\"mf\">2<\/span><span class=\"p\">].<\/span><span class=\"nx\">args<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">].<\/span><span class=\"nx\">toNumber<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">listNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId1<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Minted and listed <\/span><span class=\"si\">${<\/span><span class=\"nx\">tokenId1<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">txn2<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">mint<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"URI1\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">tokenId2<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">txn2<\/span><span class=\"p\">.<\/span><span class=\"nx\">logs<\/span><span class=\"p\">[<\/span><span class=\"mf\">2<\/span><span class=\"p\">].<\/span><span class=\"nx\">args<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">].<\/span><span class=\"nx\">toNumber<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">listNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId2<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Minted and listed <\/span><span class=\"si\">${<\/span><span class=\"nx\">tokenId2<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">txn3<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">mint<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"URI1\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">tokenId3<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">txn3<\/span><span class=\"p\">.<\/span><span class=\"nx\">logs<\/span><span class=\"p\">[<\/span><span class=\"mf\">2<\/span><span class=\"p\">].<\/span><span class=\"nx\">args<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">].<\/span><span class=\"nx\">toNumber<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">listNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId3<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Minted and listed <\/span><span class=\"si\">${<\/span><span class=\"nx\">tokenId3<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">logNftLists<\/span><span class=\"p\">(<\/span><span class=\"nx\">marketplace<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'BUY 2 NFTs'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">buyNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId1<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"mf\">1<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">buyNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId2<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"mf\">1<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">logNftLists<\/span><span class=\"p\">(<\/span><span class=\"nx\">marketplace<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'RESELL 1 NFT'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">resellNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPets<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId2<\/span><span class=\"p\">,<\/span> <span class=\"mf\">1<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">})<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">logNftLists<\/span><span class=\"p\">(<\/span><span class=\"nx\">marketplace<\/span><span class=\"p\">)<\/span>\r\n\r\n  <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Doh! '<\/span><span class=\"p\">,<\/span> <span class=\"nx\">err<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"p\">}<\/span>\r\n  <span class=\"nx\">cb<\/span><span class=\"p\">();<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">main<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>In this script, you can use\u00a0<a href=\"https:\/\/trufflesuite.com\/docs\/truffle\/getting-started\/running-migrations\/#artifactsrequire\"><code>artifacts.require<\/code><\/a>\u00a0to gain access to the contract abstractions. Then, we interact with the contracts using the\u00a0<a href=\"https:\/\/github.com\/trufflesuite\/truffle\/blob\/master\/packages\/contract\/README.md\"><code>@truffle\/contracts<\/code><\/a>\u00a0convenience library. You can use this functionality to\u00a0<a href=\"https:\/\/trufflesuite.com\/docs\/truffle\/testing\/testing-your-contracts\/\">write unit tests<\/a>\u00a0in Truffle in javasacript or typescript. Note that if you use typescript, you&#8217;ll need to create a\u00a0<code>tsconfig.json<\/code>\u00a0file and use\u00a0<code>tsc<\/code>\u00a0to compile down to javascript. You can read more about\u00a0<code>tsc<\/code>\u00a0<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/tsconfig-json.html\">here<\/a>.<\/p>\n<p>\u00a0<\/p>\n<p>To run this script, you&#8217;ll need to fill in\u00a0<code>FIRST_ACCOUNT_ADDRESS<\/code>\u00a0to query the listed NFTs. By default, Truffle uses the first account available to execute functions. You can get this address by heading over to your Ganache GUI and copy\/pasting the first account address.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/ganache_account_key.png\" alt=\"first account key\" \/><\/p>\n<p>Run\u00a0<code>truffle exec scripts\/run.js<\/code>, and your output should look what&#8217;s below:<\/p>\n<p>\u00a0<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_13\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_13 > code\"><\/button><code>MINT AND LIST <span class=\"m\">3<\/span> NFTs\r\nlistedNfts: <span class=\"m\">3<\/span>\r\nmyNfts: <span class=\"m\">0<\/span>\r\nmyListedNfts <span class=\"m\">3<\/span>\r\nBUY <span class=\"m\">2<\/span> NFTs\r\nlistedNfts: <span class=\"m\">1<\/span>\r\nmyNfts: <span class=\"m\">2<\/span>\r\nmyListedNfts <span class=\"m\">1<\/span>\r\nRESELL <span class=\"m\">1<\/span> NFT\r\nlistedNfts: <span class=\"m\">2<\/span>\r\nmyNfts: <span class=\"m\">1<\/span>\r\nmyListedNfts <span class=\"m\">1<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>Success! If you want to deploy your contracts on a populated blockchain, you can use Ganache to\u00a0<a href=\"https:\/\/trufflesuite.com\/blog\/introducing-ganache-7\/#new-ganache-7-features\">fork mainnet with zero config<\/a>.<\/p>\n<p>\u00a0<\/p>\n<h2 id=\"other-ways-to-deploy\">Other Ways to Deploy<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#other-ways-to-deploy\">\u00b6<\/a><\/h2>\n<h3 id=\"deploy-to-truffle-dashboards\">Deploy to Truffle Dashboards<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-to-truffle-dashboards\">\u00b6<\/a><\/h3>\n<p>In this tutorial, we&#8217;ll take you through how to deploy to a testnet using\u00a0<a href=\"https:\/\/trufflesuite.com\/docs\/truffle\/getting-started\/using-the-truffle-dashboard\/\">Truffle dashboards<\/a>, which allows you to sign your transactions using MetaMask. This allows you to keep your private key safe, since you don&#8217;t have to save it locally. In order to do so, you&#8217;ll need to get some test eth from a\u00a0<a href=\"https:\/\/faucet.paradigm.xyz\/\">faucet<\/a>.<\/p>\n<p>First, run\u00a0<code>truffle dashboard<\/code>\u00a0in a separate terminal window. It should open truffle dashboards at http:\/\/127.0.0.1:24012\/. Then, you can use your MetaMask wallet to connect to a network of your choice. In this case, we&#8217;ll select the Goerli network.<\/p>\n<p>Next, migrate your contract to dashboards using\u00a0<code>truffle migrate --network dashboard<\/code>. If you head back to the dashboard tab, you&#8217;ll see the request to sign using MetaMask. Hit accept, and voila! Head back to the terminal, and you should see the that your contracts were deployed.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/dashboard.gif\" alt=\"GIF of using dashboards\" \/><\/p>\n<p>After changing the account number, you can execute the script again to test:\u00a0<code>truffle exec scripts\/run.js<\/code><\/p>\n<h3 id=\"deploy-using-a-env-file\">Deploy Using a\u00a0<code>.env<\/code>\u00a0File<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-using-a-env-file\">\u00b6<\/a><\/h3>\n<p>If you don&#8217;t want to use Dashboards, you can modify your Truffle config files to use environment variables you set up. Create a\u00a0<code>.env<\/code>\u00a0file with the following code:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_14\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_14 > code\"><\/button><code><span class=\"nv\">MNEMONIC<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"candy maple cake sugar pudding cream honey rich smooth crumble sweet treat\"<\/span>\r\n<span class=\"nv\">INFURA_KEY<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"<Your Infura project key>\"<\/span>\r\n<span class=\"nv\">GANACHE_MNEMONIC<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"<Your Ganache mnemonic>\"<\/span>\r\n<span class=\"nv\">GOERLI_MNEMONIC<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"<Your Metamask mnemonic>\"<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>The\u00a0<code>.gitignore<\/code>\u00a0already ignores\u00a0<code>.env<\/code>, but since you&#8217;re populating your mnemonic\/secret key here, PLEASE DO NOT COMMIT THIS ANYWHERE PUBLIC.<\/p>\n<p>Then, just run\u00a0<code>truffle migrate --network [NETWORK NAME]<\/code>\u00a0or\u00a0<code>npm run migrate:ovm --network=[NETWORK NAME]<\/code><\/p>\n<h3 id=\"deploy-to-optimistic-goerli\">Deploy to Optimistic Goerli<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-to-optimistic-goerli\">\u00b6<\/a><\/h3>\n<p>Since Optimism is EVM equivalent with\u00a0<a href=\"https:\/\/community.optimism.io\/docs\/developers\/build\/differences\/\">small exceptions<\/a>, we can just copy our contracts from the\u00a0<code>contracts\/ethereum<\/code>\u00a0over to\u00a0<code>contracts\/optimism<\/code>.<\/p>\n<p>To get Eth for Optimistic Goerli, you can use this\u00a0<a href=\"https:\/\/optimismfaucet.xyz\/\">faucet<\/a>. You&#8217;ll need to sign up with a Github account older than 1 month and be following at least 5 repos: &#8211;\u00a0<a href=\"https:\/\/github.com\/trufflesuite\">trufflesuite<\/a>\u00a0&#8211;\u00a0<a href=\"https:\/\/github.com\/truffle-box\">truffle-box<\/a>\u00a0&#8211;\u00a0<a href=\"https:\/\/github.com\/INFURA\">Infura<\/a>\u00a0&#8211;\u00a0<a href=\"https:\/\/github.com\/metamask\">MetaMask<\/a>\u00a0&#8211;\u00a0<a href=\"https:\/\/github.com\/ethereum-optimism\">Optimism<\/a><\/p>\n<p>Our box already includes the Optimistic Goerli configuration in\u00a0<code>truffle-confg.ovm.js<\/code>. Run\u00a0<code>npm run migrate:ovm --network=optimistic_goerli<\/code>\u00a0to deploy, and\u00a0<code>npm run exec:ovm scripts\/run.js --network=optimistic_goerli<\/code>\u00a0to test!<\/p>\n<p>Since we are using a testnet, connectivity can get a bit flaky. You can try again by running the\u00a0<code>migrate<\/code>\u00a0command with\u00a0<code>--reset<\/code>. Alternatively, you might see occasionally see something like this:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_15\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_15 > code\"><\/button><code>TypeError: Cannot <span class=\"nb\">read<\/span> properties of null <span class=\"o\">(<\/span>reading <span class=\"s1\">'from'<\/span><span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>In which case, you can specify the\u00a0<code>from<\/code>\u00a0address in the deploy script as follows (<code>ACCOUNT_ADDRESS<\/code>\u00a0is the address that will be signing the transaction):<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_16\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_16 > code\"><\/button><code><span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">deployer<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">await<\/span> <span class=\"nx\">deployer<\/span><span class=\"p\">.<\/span><span class=\"nx\">deploy<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"nx\">marketplace<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">deployed<\/span><span class=\"p\">();<\/span>\r\n  <span class=\"k\">await<\/span> <span class=\"nx\">deployer<\/span><span class=\"p\">.<\/span><span class=\"nx\">deploy<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">,<\/span> <span class=\"nx\">marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"s2\">\"ACCOUNT_ADDRESS\"<\/span><span class=\"p\">});<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"deploy-to-optimism-locally\">Deploy to Optimism Locally<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-to-optimism-locally\">\u00b6<\/a><\/h3>\n<p>You can also deploy to a locally running instance of Optimism. You&#8217;ll need to have very\u00a0<a href=\"https:\/\/community.optimism.io\/docs\/developers\/build\/dev-node\/#\">specific system requirements<\/a>. Make sure ports 9545 and 8545 are free, and then run:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_17\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_17 > code\"><\/button><code>npm run installLocalOptimism\r\nnpm run startLocalOptimism\r\n<\/code><\/pre>\n<\/div>\n<h2 id=\"create-your-front-end\">Create Your Front End<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#create-your-front-end\">\u00b6<\/a><\/h2>\n<p>First, we need to install some packages to get our client up and running:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_18\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_18 > code\"><\/button><code><span class=\"nb\">cd<\/span> client\r\nnpm install axios\r\nnpm install web3modal\r\nnpm install web3\r\nnpm install ipfs-http-client\r\n<\/code><\/pre>\n<\/div>\n<p>Then, we need to create or edit 6 files that sit under\u00a0<code>client\/pages<\/code>:<\/p>\n<h3 id=\"_appjs\"><code>_app.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#_appjs\">\u00b6<\/a><\/h3>\n<p>This file organizes the link routing<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_19\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_19 > code\"><\/button><code><span class=\"k\">import<\/span> <span class=\"s1\">'..\/styles\/globals.css'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Link<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'next\/link'<\/span>\r\n\r\n<span class=\"kd\">function<\/span> <span class=\"nx\">MyApp<\/span><span class=\"p\">({<\/span> <span class=\"nx\">Component<\/span><span class=\"p\">,<\/span> <span class=\"nx\">pageProps<\/span> <span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n    <span class=\"o\"><<\/span><span class=\"nx\">div<\/span><span class=\"o\">><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">nav<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"border-b p-6\"<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-4xl font-bold\"<\/span><span class=\"o\">><\/span><span class=\"nx\">Bored<\/span> <span class=\"nx\">Pet<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"flex mt-4\"<\/span><span class=\"o\">><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">Link<\/span> <span class=\"nx\">href<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"\/\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">a<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mr-4 text-teal-400\"<\/span><span class=\"o\">><\/span>\r\n              <span class=\"nx\">Home<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"err\">\/a><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/Link><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">Link<\/span> <span class=\"nx\">href<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"\/create-and-list-nft\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">a<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mr-6 text-teal-400\"<\/span><span class=\"o\">><\/span>\r\n              <span class=\"nx\">Sell<\/span> <span class=\"nx\">a<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">NFT<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"err\">\/a><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/Link><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">Link<\/span> <span class=\"nx\">href<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"\/my-nfts\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">a<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mr-6 text-teal-400\"<\/span><span class=\"o\">><\/span>\r\n              <span class=\"nx\">My<\/span> <span class=\"nx\">NFTs<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"err\">\/a><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/Link><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">Link<\/span> <span class=\"nx\">href<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"\/my-listed-nfts\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">a<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mr-6 text-teal-400\"<\/span><span class=\"o\">><\/span>\r\n              <span class=\"nx\">My<\/span> <span class=\"nx\">Listed<\/span> <span class=\"nx\">NFTs<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"err\">\/a><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/Link><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/nav><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">Component<\/span> <span class=\"p\">{...<\/span><span class=\"nx\">pageProps<\/span><span class=\"p\">}<\/span> <span class=\"o\">\/><\/span>\r\n    <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n  <span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"nx\">MyApp<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<h3 id=\"indexjs\"><code>index.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#indexjs\">\u00b6<\/a><\/h3>\n<p>Thie file is the Home tab, where a user can see and buy all of the listed NFTs.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_20\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_20 > code\"><\/button><code tabindex=\"0\"><span class=\"k\">import<\/span> <span class=\"nx\">Web3<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3Modal<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3modal'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useEffect<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useState<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'react'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">axios<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'axios'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">Home<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setNfts<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">([])<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">loadingState<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setLoadingState<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'not-loaded'<\/span><span class=\"p\">)<\/span>\r\n\r\n  <span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">},<\/span> <span class=\"p\">[])<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\">\/\/ Get all listed NFTs<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">listings<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">getListedNfts<\/span><span class=\"p\">().<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"c1\">\/\/ Iterate over the listed NFTs and retrieve their metadata<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">nfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nb\">Promise<\/span><span class=\"p\">.<\/span><span class=\"nx\">all<\/span><span class=\"p\">(<\/span><span class=\"nx\">listings<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">(<\/span><span class=\"k\">async<\/span> <span class=\"p\">(<\/span><span class=\"nx\">i<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">tokenURI<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPetsContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">(<\/span><span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">).<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">meta<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">nft<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"kt\">i.price<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">tokenId<\/span><span class=\"o\">:<\/span> <span class=\"kt\">i.tokenId<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">seller<\/span><span class=\"o\">:<\/span> <span class=\"kt\">i.seller<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">owner<\/span><span class=\"o\">:<\/span> <span class=\"kt\">i.buyer<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"kt\">meta.data.image<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">name<\/span><span class=\"o\">:<\/span> <span class=\"kt\">meta.data.name<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">description<\/span><span class=\"o\">:<\/span> <span class=\"kt\">meta.data.description<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"p\">}<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nx\">nft<\/span>\r\n      <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"kc\">null<\/span>\r\n      <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}))<\/span>\r\n    <span class=\"nx\">setNfts<\/span><span class=\"p\">(<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">nft<\/span> <span class=\"o\">!==<\/span> <span class=\"kc\">null<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"nx\">setLoadingState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'loaded'<\/span><span class=\"p\">)<\/span> \r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">buyNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">accounts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">getAccounts<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">buyNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">).<\/span><span class=\"nx\">send<\/span><span class=\"p\">({<\/span> <span class=\"nx\">from<\/span><span class=\"o\">:<\/span> <span class=\"kt\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">],<\/span> <span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"kt\">nft.price<\/span> <span class=\"p\">});<\/span>\r\n    <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">loadingState<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">'loaded'<\/span> <span class=\"o\">&&<\/span> <span class=\"o\">!<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span><span class=\"o\"><<\/span><span class=\"nx\">h1<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"px-20 py-10 text-3xl\"<\/span><span class=\"o\">><\/span><span class=\"nx\">No<\/span> <span class=\"nx\">pets<\/span> <span class=\"nx\">available<\/span><span class=\"o\">!<<\/span><span class=\"err\">\/h1>)<\/span>\r\n  <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"flex justify-center\"<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"px-4\"<\/span> <span class=\"nx\">style<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">maxWidth<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'1600px'<\/span> <span class=\"p\">}<\/span> <span class=\"p\">}<\/span><span class=\"o\">><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">((<\/span><span class=\"nx\">nft<\/span><span class=\"p\">,<\/span> <span class=\"nx\">i<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"p\">(<\/span>\r\n                <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">key<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">i<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"border shadow rounded-xl overflow-hidden\"<\/span><span class=\"o\">><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">img<\/span> <span class=\"nx\">src<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span><span class=\"p\">}<\/span> <span class=\"o\">\/><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4\"<\/span><span class=\"o\">><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">style<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">height<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'64px'<\/span> <span class=\"p\">}<\/span> <span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl font-semibold\"<\/span><span class=\"o\">><\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">name<\/span><span class=\"p\">}<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">style<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">height<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'70px'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">overflow<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'hidden'<\/span>  <span class=\"p\">}<\/span> <span class=\"p\">}<\/span><span class=\"o\">><\/span>\r\n                      <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-gray-400\"<\/span><span class=\"o\">><\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">description<\/span><span class=\"p\">}<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4 bg-black\"<\/span><span class=\"o\">><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl font-bold text-white\"<\/span><span class=\"o\">><\/span><span class=\"p\">{<\/span><span class=\"nx\">Web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">utils<\/span><span class=\"p\">.<\/span><span class=\"nx\">fromWei<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"ether\"<\/span><span class=\"p\">)}<\/span> <span class=\"nx\">ETH<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-4 w-full bg-teal-400 text-white font-bold py-2 px-12 rounded\"<\/span> <span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">buyNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">)}<\/span><span class=\"o\">><\/span><span class=\"nx\">Buy<\/span><span class=\"o\"><<\/span><span class=\"err\">\/button><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n              <span class=\"p\">))<\/span>\r\n            <span class=\"p\">}<\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n    <span class=\"p\">)<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"create-and-list-nftjs\"><code>create-and-list-nft.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#create-and-list-nftjs\">\u00b6<\/a><\/h3>\n<p>This is the Sell tab, where a user can create and list an NFT.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_21\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_21 > code\"><\/button><code><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useState<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'react'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3Modal<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3modal'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">create<\/span> <span class=\"kr\">as<\/span> <span class=\"nx\">ipfsHttpClient<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'ipfs-http-client'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useRouter<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'next\/router'<\/span>\r\n\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">client<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">ipfsHttpClient<\/span><span class=\"p\">(<\/span><span class=\"s1\">'https:\/\/ipfs.infura.io:5001\/api\/v0'<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">CreateItem<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">fileUrl<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setFileUrl<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"kc\">null<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">({<\/span> <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span> <span class=\"nx\">name<\/span><span class=\"o\">:<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span> <span class=\"nx\">description<\/span><span class=\"o\">:<\/span> <span class=\"s1\">''<\/span> <span class=\"p\">})<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"nx\">router<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useRouter<\/span><span class=\"p\">()<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">onChange<\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c1\">\/\/ upload image to IPFS<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">file<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">files<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">]<\/span>\r\n    <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"kd\">const<\/span> <span class=\"nx\">added<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">client<\/span><span class=\"p\">.<\/span><span class=\"nx\">add<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"nx\">file<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">progress<\/span><span class=\"o\">:<\/span> <span class=\"p\">(<\/span><span class=\"nx\">prog<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`received: <\/span><span class=\"si\">${<\/span><span class=\"nx\">prog<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span>\r\n      <span class=\"p\">)<\/span>\r\n      <span class=\"kd\">const<\/span> <span class=\"nx\">url<\/span> <span class=\"o\">=<\/span> <span class=\"sb\">`https:\/\/ipfs.infura.io\/ipfs\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">added<\/span><span class=\"p\">.<\/span><span class=\"nx\">path<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span>\r\n      <span class=\"nx\">setFileUrl<\/span><span class=\"p\">(<\/span><span class=\"nx\">url<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Error uploading file: '<\/span><span class=\"p\">,<\/span> <span class=\"nx\">error<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"p\">}<\/span>  \r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">uploadToIPFS<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">name<\/span><span class=\"p\">,<\/span> <span class=\"nx\">description<\/span><span class=\"p\">,<\/span> <span class=\"nx\">price<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">formInput<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">name<\/span> <span class=\"o\">||<\/span> <span class=\"o\">!<\/span><span class=\"nx\">description<\/span> <span class=\"o\">||<\/span> <span class=\"o\">!<\/span><span class=\"nx\">price<\/span> <span class=\"o\">||<\/span> <span class=\"o\">!<\/span><span class=\"nx\">fileUrl<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">return<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"c1\">\/\/ first, upload metadata to IPFS<\/span>\r\n      <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nx\">stringify<\/span><span class=\"p\">({<\/span>\r\n        <span class=\"nx\">name<\/span><span class=\"p\">,<\/span> <span class=\"nx\">description<\/span><span class=\"p\">,<\/span> <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"nx\">fileUrl<\/span>\r\n      <span class=\"p\">})<\/span>\r\n      <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">added<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">client<\/span><span class=\"p\">.<\/span><span class=\"nx\">add<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">url<\/span> <span class=\"o\">=<\/span> <span class=\"sb\">`https:\/\/ipfs.infura.io\/ipfs\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">added<\/span><span class=\"p\">.<\/span><span class=\"nx\">path<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span>\r\n        <span class=\"c1\">\/\/ after metadata is uploaded to IPFS, return the URL to use it in the transaction<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nx\">url<\/span>\r\n      <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'Error uploading file: '<\/span><span class=\"p\">,<\/span> <span class=\"nx\">error<\/span><span class=\"p\">)<\/span>\r\n      <span class=\"p\">}<\/span> \r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">listNFTForSale<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">url<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">uploadToIPFS<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\">\/\/ Mint the NFT<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContractAddress<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">boredPetsContractAddress<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">accounts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">getAccounts<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">let<\/span> <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">getListingFee<\/span><span class=\"p\">().<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">.<\/span><span class=\"nx\">toString<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"nx\">boredPetsContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">mint<\/span><span class=\"p\">(<\/span><span class=\"nx\">url<\/span><span class=\"p\">).<\/span><span class=\"nx\">send<\/span><span class=\"p\">({<\/span> <span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">]<\/span> <span class=\"p\">}).<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">'receipt'<\/span><span class=\"p\">,<\/span> <span class=\"kd\">function<\/span> <span class=\"p\">(<\/span><span class=\"nx\">receipt<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'minted'<\/span><span class=\"p\">);<\/span>\r\n        <span class=\"c1\">\/\/ List the NFT<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">tokenId<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">receipt<\/span><span class=\"p\">.<\/span><span class=\"nx\">events<\/span><span class=\"p\">.<\/span><span class=\"nx\">NFTMinted<\/span><span class=\"p\">.<\/span><span class=\"nx\">returnValues<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">];<\/span>\r\n        <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">listNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">boredPetsContractAddress<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenId<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">utils<\/span><span class=\"p\">.<\/span><span class=\"nx\">toWei<\/span><span class=\"p\">(<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"ether\"<\/span><span class=\"p\">))<\/span>\r\n            <span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">({<\/span> <span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">],<\/span> <span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span> <span class=\"p\">}).<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">'receipt'<\/span><span class=\"p\">,<\/span> <span class=\"kd\">function<\/span> <span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n                <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">'listed'<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"nx\">router<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">(<\/span><span class=\"s1\">'\/'<\/span><span class=\"p\">)<\/span>\r\n            <span class=\"p\">});<\/span>\r\n    <span class=\"p\">});<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n    <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"flex justify-center\"<\/span><span class=\"o\">><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"w-1\/2 flex flex-col pb-12\"<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">input<\/span> \r\n          <span class=\"nx\">placeholder<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"Asset Name\"<\/span>\r\n          <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-8 border rounded p-4\"<\/span>\r\n          <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">e<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">name<\/span><span class=\"o\">:<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span> <span class=\"p\">})}<\/span>\r\n        <span class=\"o\">\/><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">textarea<\/span>\r\n          <span class=\"nx\">placeholder<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"Asset Description\"<\/span>\r\n          <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-2 border rounded p-4\"<\/span>\r\n          <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">e<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">description<\/span><span class=\"o\">:<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span> <span class=\"p\">})}<\/span>\r\n        <span class=\"o\">\/><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">input<\/span>\r\n          <span class=\"nx\">placeholder<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"Asset Price in Eth\"<\/span>\r\n          <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-2 border rounded p-4\"<\/span>\r\n          <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">e<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span> <span class=\"p\">})}<\/span>\r\n        <span class=\"o\">\/><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">input<\/span>\r\n          <span class=\"nx\">type<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"file\"<\/span>\r\n          <span class=\"nx\">name<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"Asset\"<\/span>\r\n          <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"my-4\"<\/span>\r\n          <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">onChange<\/span><span class=\"p\">}<\/span>\r\n        <span class=\"o\">\/><\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">fileUrl<\/span> <span class=\"o\">&&<\/span> <span class=\"p\">(<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">img<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"rounded mt-4\"<\/span> <span class=\"nx\">width<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"350\"<\/span> <span class=\"nx\">src<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">fileUrl<\/span><span class=\"p\">}<\/span> <span class=\"o\">\/><\/span>\r\n          <span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">listNFTForSale<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"font-bold mt-4 bg-teal-400 text-white rounded p-4 shadow-lg\"<\/span><span class=\"o\">><\/span>\r\n          <span class=\"nx\">Mint<\/span> <span class=\"nx\">and<\/span> <span class=\"nx\">list<\/span> <span class=\"nx\">NFT<\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/button><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n    <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n  <span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"my-nftsjs\"><code>my-nfts.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#my-nftsjs\">\u00b6<\/a><\/h3>\n<p>This is the My NFTs tab, where the user can see the NFTs they own and choose to resell.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_22\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_22 > code\"><\/button><code tabindex=\"0\"><span class=\"k\">import<\/span> <span class=\"nx\">Web3<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useEffect<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useState<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'react'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">axios<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'axios'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3Modal<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3modal'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useRouter<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'next\/router'<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">MyAssets<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setNfts<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">([])<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">loadingState<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setLoadingState<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'not-loaded'<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"nx\">router<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useRouter<\/span><span class=\"p\">()<\/span>\r\n\r\n  <span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">},<\/span> <span class=\"p\">[])<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContractAddress<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">boredPetsContractAddress<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">accounts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">getAccounts<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">getMyNfts<\/span><span class=\"p\">().<\/span><span class=\"nx\">call<\/span><span class=\"p\">({<\/span><span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">]})<\/span>\r\n\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">nfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nb\">Promise<\/span><span class=\"p\">.<\/span><span class=\"nx\">all<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">(<\/span><span class=\"k\">async<\/span> <span class=\"nx\">i<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">tokenURI<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPetsContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">(<\/span><span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">).<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">meta<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">let<\/span> <span class=\"nx\">nft<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">tokenId<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">seller<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">seller<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">owner<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">buyer<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"nx\">meta<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">name<\/span><span class=\"o\">:<\/span> <span class=\"nx\">meta<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">name<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">description<\/span><span class=\"o\">:<\/span> <span class=\"nx\">meta<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">description<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">tokenURI<\/span><span class=\"o\">:<\/span> <span class=\"nx\">tokenURI<\/span>\r\n        <span class=\"p\">}<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nx\">nft<\/span>\r\n      <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"kc\">null<\/span>\r\n      <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"p\">}))<\/span>\r\n    <span class=\"nx\">setNfts<\/span><span class=\"p\">(<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">nft<\/span> <span class=\"o\">!==<\/span> <span class=\"kc\">null<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"nx\">setLoadingState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'loaded'<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"kd\">function<\/span> <span class=\"nx\">listNFT<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nx\">router<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">(<\/span><span class=\"sb\">`\/resell-nft?id=<\/span><span class=\"si\">${<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"si\">}<\/span><span class=\"sb\">&tokenURI=<\/span><span class=\"si\">${<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenURI<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">loadingState<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">'loaded'<\/span> <span class=\"o\">&&<\/span> <span class=\"o\">!<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span><span class=\"o\"><<\/span><span class=\"nx\">h1<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"py-10 px-20 text-3xl\"<\/span><span class=\"o\">><\/span><span class=\"nx\">No<\/span> <span class=\"nx\">NFTs<\/span> <span class=\"nx\">owned<\/span><span class=\"o\"><<\/span><span class=\"err\">\/h1>);<\/span>\r\n  <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"flex justify-center\"<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4\"<\/span><span class=\"o\">><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">((<\/span><span class=\"nx\">nft<\/span><span class=\"p\">,<\/span> <span class=\"nx\">i<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"p\">(<\/span>\r\n                <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">key<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">i<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"border shadow rounded-xl overflow-hidden\"<\/span><span class=\"o\">><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">img<\/span> <span class=\"nx\">src<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"rounded\"<\/span> <span class=\"o\">\/><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4\"<\/span><span class=\"o\">><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">style<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">height<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'64px'<\/span> <span class=\"p\">}<\/span> <span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl font-semibold\"<\/span><span class=\"o\">><\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">name<\/span><span class=\"p\">}<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">style<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">height<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'70px'<\/span><span class=\"p\">,<\/span> <span class=\"nx\">overflow<\/span><span class=\"o\">:<\/span> <span class=\"s1\">'hidden'<\/span> <span class=\"p\">}<\/span> <span class=\"p\">}<\/span><span class=\"o\">><\/span>\r\n                      <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-gray-400\"<\/span><span class=\"o\">><\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">description<\/span><span class=\"p\">}<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4 bg-black\"<\/span><span class=\"o\">><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl font-bold text-white\"<\/span><span class=\"o\">><\/span><span class=\"nx\">Price<\/span> <span class=\"o\">-<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">utils<\/span><span class=\"p\">.<\/span><span class=\"nx\">fromWei<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"ether\"<\/span><span class=\"p\">)}<\/span> <span class=\"nx\">Eth<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-4 w-full bg-teal-400 text-white font-bold py-2 px-12 rounded\"<\/span> <span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">listNFT<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">)}<\/span><span class=\"o\">><\/span><span class=\"nx\">List<\/span><span class=\"o\"><<\/span><span class=\"err\">\/button><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n              <span class=\"p\">))<\/span>\r\n            <span class=\"p\">}<\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n    <span class=\"p\">);<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"resell-nftjs\"><code>resell-nft.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#resell-nftjs\">\u00b6<\/a><\/h3>\n<p>This is the page the user is directed to to resell their NFTs.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_23\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_23 > code\"><\/button><code tabindex=\"0\"><span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useEffect<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useState<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'react'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useRouter<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'next\/router'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">axios<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'axios'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3Modal<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3modal'<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">ResellNFT<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">({<\/span> <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"s1\">''<\/span><span class=\"p\">,<\/span> <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"s1\">''<\/span> <span class=\"p\">})<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"nx\">router<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useRouter<\/span><span class=\"p\">()<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">id<\/span><span class=\"p\">,<\/span> <span class=\"nx\">tokenURI<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">router<\/span><span class=\"p\">.<\/span><span class=\"nx\">query<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">image<\/span><span class=\"p\">,<\/span> <span class=\"nx\">price<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">formInput<\/span>\r\n\r\n  <span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span> <span class=\"nx\">fetchNFT<\/span><span class=\"p\">()<\/span> <span class=\"p\">},<\/span> <span class=\"p\">[<\/span><span class=\"nx\">id<\/span><span class=\"p\">])<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">fetchNFT<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">meta<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nx\">updateFormInput<\/span><span class=\"p\">(<\/span><span class=\"nx\">state<\/span> <span class=\"p\">=><\/span> <span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">state<\/span><span class=\"p\">,<\/span> <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"nx\">meta<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span> <span class=\"p\">}))<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">listNFTForSale<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">price<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"k\">return<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">let<\/span> <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">getListingFee<\/span><span class=\"p\">().<\/span><span class=\"nx\">call<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"nx\">listingFee<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">listingFee<\/span><span class=\"p\">.<\/span><span class=\"nx\">toString<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">accounts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">getAccounts<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">resellNft<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">,<\/span> <span class=\"nx\">id<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">utils<\/span><span class=\"p\">.<\/span><span class=\"nx\">toWei<\/span><span class=\"p\">(<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"ether\"<\/span><span class=\"p\">))<\/span>\r\n            <span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">({<\/span> <span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">],<\/span> <span class=\"nx\">value<\/span><span class=\"o\">:<\/span> <span class=\"nx\">listingFee<\/span> <span class=\"p\">}).<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">'receipt'<\/span><span class=\"p\">,<\/span> <span class=\"kd\">function<\/span> <span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n                <span class=\"nx\">router<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">(<\/span><span class=\"s1\">'\/'<\/span><span class=\"p\">)<\/span>\r\n            <span class=\"p\">});<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n    <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"flex justify-center\"<\/span><span class=\"o\">><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"w-1\/2 flex flex-col pb-12\"<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">input<\/span>\r\n          <span class=\"nx\">placeholder<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"Asset Price in Eth\"<\/span>\r\n          <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"mt-2 border rounded p-4\"<\/span>\r\n          <span class=\"nx\">onChange<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">e<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">updateFormInput<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">formInput<\/span><span class=\"p\">,<\/span> <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span> <span class=\"p\">})}<\/span>\r\n        <span class=\"o\">\/><\/span>\r\n        <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">image<\/span> <span class=\"o\">&&<\/span> <span class=\"p\">(<\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">img<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"rounded mt-4\"<\/span> <span class=\"nx\">width<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"350\"<\/span> <span class=\"nx\">src<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">image<\/span><span class=\"p\">}<\/span> <span class=\"o\">\/><\/span>\r\n          <span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">button<\/span> <span class=\"nx\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">listNFTForSale<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"font-bold mt-4 bg-teal-400 text-white rounded p-4 shadow-lg\"<\/span><span class=\"o\">><\/span>\r\n          <span class=\"nx\">List<\/span> <span class=\"nx\">NFT<\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/button><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n    <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n  <span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"my-listed-nftsjs\"><code>my-listed-nfts.js<\/code><a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#my-listed-nftsjs\">\u00b6<\/a><\/h3>\n<p>This is the My Listed NFTs tab, where users can see what NFTs they have listed for sale.<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_24\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_24 > code\"><\/button><code><span class=\"k\">import<\/span> <span class=\"nx\">Web3<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">useEffect<\/span><span class=\"p\">,<\/span> <span class=\"nx\">useState<\/span> <span class=\"p\">}<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'react'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">axios<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'axios'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Web3Modal<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'web3modal'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">CreatorDashboard<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setNfts<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">([])<\/span>\r\n  <span class=\"kd\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">loadingState<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setLoadingState<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'not-loaded'<\/span><span class=\"p\">)<\/span>\r\n\r\n  <span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">},<\/span> <span class=\"p\">[])<\/span>\r\n\r\n  <span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">loadNFTs<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3Modal<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3Modal<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">provider<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3Modal<\/span><span class=\"p\">.<\/span><span class=\"nx\">connect<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">web3<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">Web3<\/span><span class=\"p\">(<\/span><span class=\"nx\">provider<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">networkId<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">net<\/span><span class=\"p\">.<\/span><span class=\"nx\">getId<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\">\/\/ Get listed NFTs<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">marketPlaceContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Marketplace<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">accounts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">getAccounts<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">listings<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">marketPlaceContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">getMyListedNfts<\/span><span class=\"p\">().<\/span><span class=\"nx\">call<\/span><span class=\"p\">({<\/span><span class=\"kr\">from<\/span><span class=\"o\">:<\/span> <span class=\"nx\">accounts<\/span><span class=\"p\">[<\/span><span class=\"mf\">0<\/span><span class=\"p\">]})<\/span>\r\n    <span class=\"c1\">\/\/ Iterate over my listed NFTs and retrieve their metadata<\/span>\r\n    <span class=\"kd\">const<\/span> <span class=\"nx\">nfts<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nb\">Promise<\/span><span class=\"p\">.<\/span><span class=\"nx\">all<\/span><span class=\"p\">(<\/span><span class=\"nx\">listings<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">(<\/span><span class=\"k\">async<\/span> <span class=\"nx\">i<\/span> <span class=\"p\">=><\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">boredPetsContract<\/span> <span class=\"o\">=<\/span> <span class=\"ow\">new<\/span> <span class=\"nx\">web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">eth<\/span><span class=\"p\">.<\/span><span class=\"nx\">Contract<\/span><span class=\"p\">(<\/span><span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">abi<\/span><span class=\"p\">,<\/span> <span class=\"nx\">BoredPetsNFT<\/span><span class=\"p\">.<\/span><span class=\"nx\">networks<\/span><span class=\"p\">[<\/span><span class=\"nx\">networkId<\/span><span class=\"p\">].<\/span><span class=\"nx\">address<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">tokenURI<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">boredPetsContract<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">(<\/span><span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">).<\/span><span class=\"nx\">call<\/span><span class=\"p\">();<\/span>\r\n        <span class=\"kd\">const<\/span> <span class=\"nx\">meta<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">axios<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">tokenURI<\/span><span class=\"p\">);<\/span>\r\n        <span class=\"kd\">let<\/span> <span class=\"nx\">item<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n          <span class=\"nx\">price<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">tokenId<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">tokenId<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">seller<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">seller<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">owner<\/span><span class=\"o\">:<\/span> <span class=\"nx\">i<\/span><span class=\"p\">.<\/span><span class=\"nx\">owner<\/span><span class=\"p\">,<\/span>\r\n          <span class=\"nx\">image<\/span><span class=\"o\">:<\/span> <span class=\"nx\">meta<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"p\">}<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nx\">item<\/span>\r\n      <span class=\"p\">}<\/span> <span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"nx\">err<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"kc\">null<\/span>\r\n      <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}))<\/span>\r\n    <span class=\"nx\">setNfts<\/span><span class=\"p\">(<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span> <span class=\"p\">=><\/span> <span class=\"nx\">nft<\/span> <span class=\"o\">!==<\/span> <span class=\"kc\">null<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"nx\">setLoadingState<\/span><span class=\"p\">(<\/span><span class=\"s1\">'loaded'<\/span><span class=\"p\">)<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">loadingState<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">'loaded'<\/span> <span class=\"o\">&&<\/span> <span class=\"o\">!<\/span><span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span><span class=\"o\"><<\/span><span class=\"nx\">h1<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"py-10 px-20 text-3xl\"<\/span><span class=\"o\">><\/span><span class=\"nx\">No<\/span> <span class=\"nx\">NFTs<\/span> <span class=\"nx\">listed<\/span><span class=\"o\"><<\/span><span class=\"err\">\/h1>)<\/span>\r\n  <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n      <span class=\"o\"><<\/span><span class=\"nx\">div<\/span><span class=\"o\">><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4\"<\/span><span class=\"o\">><\/span>\r\n          <span class=\"o\"><<\/span><span class=\"nx\">h2<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl py-2\"<\/span><span class=\"o\">><\/span><span class=\"nx\">Items<\/span> <span class=\"nx\">Listed<\/span><span class=\"o\"><<\/span><span class=\"err\">\/h2><\/span>\r\n            <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 pt-4\"<\/span><span class=\"o\">><\/span>\r\n            <span class=\"p\">{<\/span>\r\n              <span class=\"nx\">nfts<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">((<\/span><span class=\"nx\">nft<\/span><span class=\"p\">,<\/span> <span class=\"nx\">i<\/span><span class=\"p\">)<\/span> <span class=\"p\">=><\/span> <span class=\"p\">(<\/span>\r\n                <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">key<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">i<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"border shadow rounded-xl overflow-hidden\"<\/span><span class=\"o\">><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">img<\/span> <span class=\"nx\">src<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">image<\/span><span class=\"p\">}<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"rounded\"<\/span> <span class=\"o\">\/><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"p-4 bg-black\"<\/span><span class=\"o\">><\/span>\r\n                    <span class=\"o\"><<\/span><span class=\"nx\">p<\/span> <span class=\"nx\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"text-2xl font-bold text-white\"<\/span><span class=\"o\">><\/span><span class=\"nx\">Price<\/span> <span class=\"o\">-<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Web3<\/span><span class=\"p\">.<\/span><span class=\"nx\">utils<\/span><span class=\"p\">.<\/span><span class=\"nx\">fromWei<\/span><span class=\"p\">(<\/span><span class=\"nx\">nft<\/span><span class=\"p\">.<\/span><span class=\"nx\">price<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"ether\"<\/span><span class=\"p\">)}<\/span> <span class=\"nx\">Eth<\/span><span class=\"o\"><<\/span><span class=\"err\">\/p><\/span>\r\n                  <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n                <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n              <span class=\"p\">))<\/span>\r\n            <span class=\"p\">}<\/span>\r\n          <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n        <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n      <span class=\"o\"><<\/span><span class=\"err\">\/div><\/span>\r\n    <span class=\"p\">)<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"web3-client-overview\">Web3 Client Overview<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#web3-client-overview\">\u00b6<\/a><\/h3>\n<p>Let&#8217;s go over the Web3 concepts and utilities we&#8217;ve used to hook up our front end.<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Web3Modal\/web3modal\"><code>web3Modal<\/code><\/a>\u00a0is a library we use to retrieve the user&#8217;s network provider<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/ipfs-http-client\"><code>ipfs-http-client<\/code><\/a>\u00a0is a library we use to upload the NFTs metadata to IPFS<\/li>\n<li><a href=\"https:\/\/web3js.readthedocs.io\/\"><code>web3<\/code><\/a>\u00a0is a library that allows us to use our smart contract abstractions<\/li>\n<\/ul>\n<p>Depending on if you want to use your Optimism contracts or your Ethereum contracts, you&#8217;ll change the contract import path:<\/p>\n<div class=\"highlight\">\n<pre id=\"__code_25\"><button class=\"md-clipboard md-icon\" style=\"box-sizing: border-box; transition: color 0.25s ease 0s; -webkit-tap-highlight-color: transparent; background: transparent; border: 0px; font-family: inherit; font-size: inherit; margin: 1em 1em 0px 0px; padding: 0px; border-radius: 0.1rem; line-height: inherit; text-transform: none; appearance: button; color: var(--md-default-fg-color--lightest); cursor: pointer; height: 1.5em; outline: none; outline-offset: 0.1rem; position: absolute; right: 0.5em; top: 0.5em; width: 1.5em; z-index: 1;\" title=\"Copy to clipboard\" data-clipboard-target=\"#__code_25 > code\"><\/button><code><span class=\"k\">import<\/span> <span class=\"nx\">Marketplace<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/Marketplace.json'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">BoredPetsNFT<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">'..\/contracts\/optimism-contracts\/BoredPetsNFT.json'<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>When we call our contract methods with\u00a0<code>Web3.js<\/code>, we use\u00a0<code>call<\/code>\u00a0when we don&#8217;t alter the contract state, and\u00a0<code>send<\/code>\u00a0when we do. You can read more about it\u00a0<a href=\"https:\/\/web3js.readthedocs.io\/en\/v1.2.2\/web3-eth-contract.html#id25\">here<\/a>.<\/p>\n<h2 id=\"deploy-your-front-end\">Deploy Your Front End<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#deploy-your-front-end\">\u00b6<\/a><\/h2>\n<p>To see the front end in action, just use the node scripts in\u00a0<code>package.json<\/code>. Run\u00a0<code>npm run dev<\/code>\u00a0from the\u00a0<code>client<\/code>\u00a0folder, and your website should be brought up on\u00a0<code>http:\/\/localhost:3000\/<\/code>!<\/p>\n<p>Note that the front end will be using whatever network and account is set on your MetaMask extension.<\/p>\n<h3 id=\"adding-ganache-to-metamask\">Adding Ganache to MetaMask<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#adding-ganache-to-metamask\">\u00b6<\/a><\/h3>\n<p>If you would like to use Ganache as your network, you can add the network to your MetaMask wallet with the following properties:<\/p>\n<ul>\n<li>Network Name: Ganache<\/li>\n<li>New RPC URL: http:\/\/127.0.0.1:7545<\/li>\n<li>Chain ID: 1337<\/li>\n<li>Currency Symbol: ETH<\/li>\n<\/ul>\n<p>Then, import a new account. If you are using the Ganache UI, you can grab the private key by clicking on the key icon to reveal the account keys.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/get_private_key.gif\" alt=\"GIF of getting private key\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/img\/import_account.gif\" alt=\"GIF of importing account\" \/><\/p>\n<h3 id=\"adding-optimistic-ethereum-to-metamask\">Adding Optimistic Ethereum to MetaMask<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#adding-optimistic-ethereum-to-metamask\">\u00b6<\/a><\/h3>\n<p>If you would like to use your local instance of Optimism, you can add the network to your MetaMask wallet with the following properties:<\/p>\n<ul>\n<li>Network Name: Optimistic Ethereum<\/li>\n<li>New RPC URL: http:\/\/127.0.0.1:8545<\/li>\n<li>Chain ID: 17<\/li>\n<li>Currency Symbol: ETH<\/li>\n<\/ul>\n<p>Then, import a new account. You can get the list of accounts and private keys\u00a0<a href=\"https:\/\/community.optimism.io\/docs\/developers\/build\/dev-node\/#accessing-the-environment\">here<\/a>.<\/p>\n<h2 id=\"additional-notes\">Additional Notes<a class=\"headerlink\" title=\"Permanent link\" href=\"https:\/\/trufflesuite.com\/guides\/nft-marketplace\/#additional-notes\">\u00b6<\/a><\/h2>\n<p>And there you have it &#8211; a very basic marketplace! There are many ways you can build upon this project: &#8211; Allow users to bid on an NFT &#8211; Allow useres to delist their NFTs &#8211; Combining the Marketplace contract and NFT contract into one &#8211; Bridging the Optimism contracts (Truffle L2 bridge box coming soon!)<\/p>\n<p>If you&#8217;re interested in actually bridging between Ethereum and Optimism, check out our\u00a0<a href=\"https:\/\/trufflesuite.com\/blog\/introducing-the-optimism-bridge-truffle-box\/\">Optimism Bridge Box<\/a>!<\/p>\n<p>Join\u00a0<a href=\"https:\/\/github.com\/orgs\/trufflesuite\/discussions\">Github Discussions<\/a>\u00a0to join the Truffle community to discuss and ask questions!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u5730\u5740 Written by\u00a0Emil<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[24],"tags":[121],"class_list":["post-5907","post","type-post","status-publish","format-standard","hentry","category-value_docs","tag-05-"],"_links":{"self":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/5907","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/comments?post=5907"}],"version-history":[{"count":0,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/5907\/revisions"}],"wp:attachment":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/media?parent=5907"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/categories?post=5907"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/tags?post=5907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}