Issue with contract and Approving Opensea clone

Hey guys
I’m having issues with the approve and list buttons on my opensea clone I cant approve and list NFT’s for sale… I’ve narrowed it down to there is a error in the smart contract or Abi. Can someone please help me find a solution. I’ve been stuck on this for several hours and want to figure it out :slight_smile:

NFTBalance.jsx

import React, { useState } from "react";

import { useMoralis } from "react-moralis";

import { Card, Image, Tooltip, Modal, Input, Alert, Spin, Button } from "antd";

import { useNFTBalance } from "hooks/useNFTBalance";

import { FileSearchOutlined, ShoppingCartOutlined } from "@ant-design/icons";

import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";

import { getExplorer } from "helpers/networks";

import { useWeb3ExecuteFunction } from "react-moralis";

const { Meta } = Card;

const styles = {

  NFTs: {

    display: "flex",

    flexWrap: "wrap",

    WebkitBoxPack: "start",

    justifyContent: "flex-start",

    margin: "0 auto",

    maxWidth: "1000px",

    gap: "10px",

  },

};

function NFTBalance() {

  const { NFTBalance, fetchSuccess } = useNFTBalance();

  const { chainId, marketAddress, contractABI } = useMoralisDapp();

  const { Moralis } = useMoralis();

  const [visible, setVisibility] = useState(false);

  const [nftToSend, setNftToSend] = useState(null);

  const [price, setPrice] = useState(1);

  const [loading, setLoading] = useState(false);

  const contractProcessor = useWeb3ExecuteFunction();

  const contractABIJson = JSON.parse(contractABI);

  const listItemFunction = "createMarketItem";

  const ItemImage = Moralis.Object.extend("ItemImages");

  async function list(nft, listPrice) {

    setLoading(true);

    const p = listPrice * ("1e" + 18);

    const ops = {

      contractAddress: marketAddress,

      functionName: listItemFunction,

      abi: contractABIJson,

      params: {

        nftContract: nft.token_address,

        tokenId: nft.token_id,

        price: String(p),

      },

    };

    await contractProcessor.fetch({

      params: ops,

      onSuccess: () => {

        console.log("success");

        setLoading(false);

        setVisibility(false);

        addItemImage();

        succList();

      },

      onError: (error) => {

        setLoading(false);

        failList();

      },

    });

  }

  async function approveAll(nft) {

    setLoading(true);  

    console.log("nft: ", nft)

    const ops = {

      contractAddress: nft.token_address,

      functionName: "setApprovalForAll",

      abi: [{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"}],

      params: {

        operator: marketAddress,

        approved: true

      },

    };

    console.log("ops : ", ops)

    await contractProcessor.fetch({

      params: ops,

      onSuccess: () => {

        console.log("Approval Received");

        setLoading(false);

        setVisibility(false);

        succApprove();

      },

      onError: (error) => {

        setLoading(false);

        failApprove();

        console.log(error)

      },

    });

  }

  const handleSellClick = (nft) => {

    setNftToSend(nft);

    setVisibility(true);

  };

  function succList() {

    let secondsToGo = 5;

    const modal = Modal.success({

      title: "Success!",

      content: `Your NFT was listed on the marketplace`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function succApprove() {

    let secondsToGo = 5;

    const modal = Modal.success({

      title: "Success!",

      content: `Approval is now set, you may list your NFT`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function failList() {

    let secondsToGo = 5;

    const modal = Modal.error({

      title: "Error!",

      content: `There was a problem listing your NFT`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function failApprove() {

    let secondsToGo = 5;

    const modal = Modal.error({

      title: "Error!",

      content: `There was a problem with setting approval`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function addItemImage() {

    const itemImage = new ItemImage();

    itemImage.set("image", nftToSend.image);

    itemImage.set("nftContract", nftToSend.token_address);

    itemImage.set("tokenId", nftToSend.token_id);

    itemImage.set("name", nftToSend.name);

    itemImage.save();

  }

  return (

    <>

      <div style={styles.NFTs}>

        {contractABIJson.noContractDeployed && (

          <>

            <Alert

              message="No Smart Contract Details Provided. Please deploy smart contract and provide address + ABI in the MoralisDappProvider.js file"

              type="error"

            />

            <div style={{ marginBottom: "10px" }}></div>

          </>

        )}

        {!fetchSuccess && (

          <>

            <Alert

              message="Unable to fetch all NFT metadata... We are searching for a solution, please try again later!"

              type="warning"

            />

            <div style={{ marginBottom: "10px" }}></div>

          </>

        )}

        {NFTBalance &&

          NFTBalance.map((nft, index) => (

            <Card

             key={index}

              hoverable

              actions={[

                <Tooltip title="View On Blockexplorer" key={index}>

                  <FileSearchOutlined

                  key={index}

                    onClick={() =>

                      window.open(

                        `${getExplorer(chainId)}address/${nft.token_address}`,

                        "_blank"

                      )

                    }

                  />

                </Tooltip>,

                <Tooltip title="List NFT for sale" key={index}>

                  <ShoppingCartOutlined onClick={() => handleSellClick(nft)} key={index}/>

                </Tooltip>,

              ]}

              style={{ width: 240, border: "2px solid #e7eaf3" }}

              cover={

                <Image

                key={index}

                  preview={false}

                  src={nft?.image || "error"}

                  fallback="data:image/png;base64,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"

                  alt=""

                  style={{ height: "240px" }}

                />

              }

            >

              <Meta title={nft.name} description={nft.contract_type} key={index} />

            </Card>

          ))}

      </div>

     

      <Modal

       

        title={`List ${nftToSend?.name} #${nftToSend?.token_id} For Sale`}

        visible={visible}

        onCancel={() => setVisibility(false)}

        onOk={() => list(nftToSend, price)}

        okText="List"

       

        footer={[

          <Button onClick={() => setVisibility(false)}>

            Cancel

          </Button>,

          <Button onClick={() => approveAll(nftToSend)} type="primary">

            Approve

          </Button>,

          <Button onClick={() => list(nftToSend, price)} type="primary">

            List

          </Button>

        ]}

      >

        <Spin spinning={loading}>

          <img

            src={`${nftToSend?.image}`}

            style={{

              width: "250px",

              margin: "auto",

              borderRadius: "10px",

              marginBottom: "15px",

            }}

          />

          <Input

            autoFocus

            placeholder="Listing Price in ETH"

            onChange={(e) => setPrice(e.target.value)}

          />

        </Spin>

      </Modal>

    </>

  );

}

export default NFTBalance;

NFTMarketTransactions

import React, { useState } from "react";

import { useMoralis, useMoralisQuery } from "react-moralis";

import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";

import { Table, Tag, Space } from "antd";

import { PolygonCurrency} from "./Chains/Logos";

import moment from "moment";

const styles = {

  table: {

    margin: "0 auto",

    width: "1000px",

  },

};

function NFTMarketTransactions() {

  const { walletAddress } = useMoralisDapp();

  const { Moralis } = useMoralis();

  const queryItemImages = useMoralisQuery("ItemImages");

  const fetchItemImages = JSON.parse(

    JSON.stringify(queryItemImages.data, [

      "nftContract",

      "tokenId",

      "name",

      "image",

    ])

  );

  const queryMarketItems = useMoralisQuery("MarketItems");

  const fetchMarketItems = JSON.parse(

    JSON.stringify(queryMarketItems.data, [

      "updatedAt",

      "price",

      "nftContract",

      "itemId",

      "sold",

      "tokenId",

      "seller",

      "owner",

    ])

  )

    .filter(

      (item) => item.seller === walletAddress || item.owner === walletAddress

    )

    .sort((a, b) =>

      a.updatedAt < b.updatedAt ? 1 : b.updatedAt < a.updatedAt ? -1 : 0

    );

  function getImage(addrs, id) {

    const img = fetchItemImages.find(

      (element) =>

        element.nftContract === addrs &&

        element.tokenId === id

    );

    return img?.image;

  }

  function getName(addrs, id) {

    const nme = fetchItemImages.find(

      (element) =>

        element.nftContract === addrs &&

        element.tokenId === id

    );

    return nme?.name;

  }

  const columns = [

    {

      title: "Date",

      dataIndex: "date",

      key: "date",

    },

    {

      title: "Item",

      key: "item",

      render: (text, record) => (

        <Space size="middle">

          <img src={getImage(record.collection, record.item)} style={{ width: "40px", borderRadius:"4px"}} />

          <span>#{record.item}</span>

        </Space>

      ),

    },

    {

      title: "Collection",

      key: "collection",

      render: (text, record) => (

        <Space size="middle">

          <span>{getName(record.collection, record.item)}</span>

        </Space>

      ),

    },

    {

      title: "Transaction Status",

      key: "tags",

      dataIndex: "tags",

      render: (tags) => (

        <>

          {tags.map((tag) => {

            let color = "geekblue";

            let status = "BUY";

            if (tag === false) {

              color = "volcano";

              status = "waiting";

            } else if (tag === true) {

              color = "green";

              status = "confirmed";

            }

            if (tag === walletAddress) {

              status = "SELL";

            }

            return (

              <Tag color={color} key={tag}>

                {status.toUpperCase()}

              </Tag>

            );

          })}

        </>

      ),

    },

    {

      title: "Price",

      key: "price",

      dataIndex: "price",

      render: (e) => (

        <Space size="middle">

          <PolygonCurrency/>

          <span>{e}</span>

        </Space>

      ),

    }

  ];

  const data = fetchMarketItems?.map((item, index) => ({

    key: index,

    date: moment(item.updatedAt).format("DD-MM-YYYY HH:mm"),

    collection: item.nftContract,

    item: item.tokenId,

    tags: [item.seller, item.sold],

    price: item.price / ("1e" + 18)

  }));

  return (

    <>

      <div>

        <div style={styles.table}>

          <Table columns={columns} dataSource={data} />

        </div>

      </div>

    </>

  );

}

export default NFTMarketTransactions;

const columns = [

  {

    title: "Date",

    dataIndex: "date",

    key: "date",

  },

  {

    title: "Item",

    key: "item",

  },

  {

    title: "Collection",

    key: "collection",

  },

  {

    title: "Transaction Status",

    key: "tags",

    dataIndex: "tags",

  },

  {

    title: "Price",

    key: "price",

    dataIndex: "price",

  }

];

![Screenshot 2022-07-26 105849 Smart Contract issue to send to glad and john|493x500](upload://b3WFas8F8hSIVw9Zvg8IPyMdbhy.png)

marketplace Smart Contract

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";

import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";

import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol";

contract marketPlaceBoilerPlate is ReentrancyGuard {

    using Counters for Counters.Counter;

    Counters.Counter private _itemIds;

    Counters.Counter private _itemsSold;

   

     address public owner;

     

     constructor() {

         owner = msg.sender;

     }

     

     struct MarketItem {

         uint itemId;

         address nftContract;

         uint256 tokenId;

         address payable seller;

         address payable owner;

         uint256 price;

         bool sold;

     }

     

     mapping(uint256 => MarketItem) private idToMarketItem;

     

     event MarketItemCreated (

        uint indexed itemId,

        address indexed nftContract,

        uint256 indexed tokenId,

        address seller,

        address owner,

        uint256 price,

        bool sold

     );

     

     event MarketItemSold (

         uint indexed itemId,

         address owner

         );

            

    function createMarketItem(

        address nftContract,

        uint256 tokenId,

        uint256 price

        ) public payable nonReentrant {

            require(price > 0, "Price must be greater than 0");

           

            _itemIds.increment();

            uint256 itemId = _itemIds.current();

 

            idToMarketItem[itemId] =  MarketItem(

                itemId,

                nftContract,

                tokenId,

                payable(msg.sender),

                payable(address(0)),

                price,

                false

            );

           

            IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);

               

            emit MarketItemCreated(

                itemId,

                nftContract,

                tokenId,

                msg.sender,

                address(0),

                price,

                false

            );

        }

       

    function createMarketSale(

        address nftContract,

        uint256 itemId

        ) public payable nonReentrant {

            uint price = idToMarketItem[itemId].price;

            uint tokenId = idToMarketItem[itemId].tokenId;

            bool sold = idToMarketItem[itemId].sold;

            require(msg.value == price, "Please submit the asking price in order to complete the purchase");

            require(sold != true, "This Sale has alredy finnished");

            emit MarketItemSold(

                itemId,

                msg.sender

                );

            idToMarketItem[itemId].seller.transfer(msg.value);

            IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId);

            idToMarketItem[itemId].owner = payable(msg.sender);

            _itemsSold.increment();

            idToMarketItem[itemId].sold = true;

        }

       

    function fetchMarketItems() public view returns (MarketItem[] memory) {

        uint itemCount = _itemIds.current();

        uint unsoldItemCount = _itemIds.current() - _itemsSold.current();

        uint currentIndex = 0;

        MarketItem[] memory items = new MarketItem[](unsoldItemCount);

        for (uint i = 0; i < itemCount; i++) {

            if (idToMarketItem[i + 1].owner == address(0)) {

                uint currentId = i + 1;

                MarketItem storage currentItem = idToMarketItem[currentId];

                items[currentIndex] = currentItem;

                currentIndex += 1;

            }

        }

        return items;

    }

     

}

/// Thanks for inspiration: https://github.com/dabit3/polygon-ethereum-nextjs-marketplace/

The error is invalid address so double check and log the address you’re using in your options for calling the contract - you can also hardcode it to test. Make sure there’s no spaces or anything else, just a valid 0x address.

Okay ill double check. I used the address I got from the deployment of the smart contract on remix.

Hey @alex
Is this what you mean by console.logging the address I use in my options for calling the contract?
I’ve doublechecked the address and it is the correct one without spaces from the deployment of the contract

Screenshot 2022-07-26 125116 FOR FORUM

@alex
I don’t think this has anything to do with my errors but I thought i would ask just incase?

If your contract is compiling/deploying fine I think you can ignore those errors for now with the imports.

Yes you need to check any addresses you’re using and make sure your wallet is on the right chain.

1 Like

Ok sweet
it does compile and deploy fine so I won’t worry about them. I 'll triple check the addresses and what chain my wallet is using. Are these the only things it could be??
Cheers :slight_smile:

Hey @alex
Does this contract need to be deployed aswell?

Are these the only things it could be??

Based on the invalid address error, yes. Maybe there’s something else throwing that error but I don’t think so.

Does this contract need to be deployed aswell?

If you’re not interacting with it in your code, then no. I think you’re just using the marketplace contract and trying to list NFTs.

Yes all I’m trying to do is list NFT’s. Ok Ill quadruple check the address but I’m pretty positive its correct.
Thank you for all your help. I appreciate it.
Cheers

This error is still there and i did everything you and john said for it aswell. I’m not sure why its consoling this still. these are my only 2 errors and the marketplace is finished. :slight_smile:

NFTBalance

import React, { useState } from "react";

import { useMoralis } from "react-moralis";

import { Card, Image, Tooltip, Modal, Input, Alert, Spin, Button } from "antd";

import { useNFTBalance } from "hooks/useNFTBalance";

import { FileSearchOutlined, ShoppingCartOutlined } from "@ant-design/icons";

import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";

import { getExplorer } from "helpers/networks";

import { useWeb3ExecuteFunction } from "react-moralis";

const { Meta } = Card;

const styles = {

  NFTs: {

    display: "flex",

    flexWrap: "wrap",

    WebkitBoxPack: "start",

    justifyContent: "flex-start",

    margin: "0 auto",

    maxWidth: "1000px",

    gap: "10px",

  },

};

function NFTBalance() {

  const { NFTBalance, fetchSuccess } = useNFTBalance();

  const { chainId, marketAddress, contractABI } = useMoralisDapp();

  const { Moralis } = useMoralis();

  const [visible, setVisibility] = useState(false);

  const [nftToSend, setNftToSend] = useState(null);

  const [price, setPrice] = useState(1);

  const [loading, setLoading] = useState(false);

  const contractProcessor = useWeb3ExecuteFunction();

  const contractABIJson = JSON.parse(contractABI);

  const listItemFunction = "createMarketItem";

  const ItemImage = Moralis.Object.extend("ItemImages");

  async function list(nft, listPrice) {

    setLoading(true);

    const p = listPrice * ("1e" + 18);

    const ops = {

      contractAddress: marketAddress,

      functionName: listItemFunction,

      abi: contractABIJson,

      params: {

        nftContract: nft.token_address,

        tokenId: nft.token_id,

        price: String(p),

      },

    };

    await contractProcessor.fetch({

      params: ops,

      onSuccess: () => {

        console.log("success");

        setLoading(false);

        setVisibility(false);

        addItemImage();

        succList();

      },

      onError: (error) => {

        setLoading(false);

        failList();

      },

    });

  }

  async function approveAll(nft) {

    setLoading(true);  

    console.log("nft: ", nft)

    const ops = {

      contractAddress: nft.token_address,

      functionName: "setApprovalForAll",

      abi: [{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"}],

      params: {

        operator: marketAddress,

        approved: true

      },

    };

    console.log("ops : ", ops)

    await contractProcessor.fetch({

      params: ops,

      onSuccess: () => {

        console.log("Approval Received");

        setLoading(false);

        setVisibility(false);

        succApprove();

      },

      onError: (error) => {

        setLoading(false);

        failApprove();

        console.log(error)

      },

    });

  }

  const handleSellClick = (nft) => {

    setNftToSend(nft);

    setVisibility(true);

  };

  function succList() {

    let secondsToGo = 5;

    const modal = Modal.success({

      title: "Success!",

      content: `Your NFT was listed on the marketplace`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function succApprove() {

    let secondsToGo = 5;

    const modal = Modal.success({

      title: "Success!",

      content: `Approval is now set, you may list your NFT`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function failList() {

    let secondsToGo = 5;

    const modal = Modal.error({

      title: "Error!",

      content: `There was a problem listing your NFT`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function failApprove() {

    let secondsToGo = 5;

    const modal = Modal.error({

      title: "Error!",

      content: `There was a problem with setting approval`,

    });

    setTimeout(() => {

      modal.destroy();

    }, secondsToGo * 1000);

  }

  function addItemImage() {

    const itemImage = new ItemImage();

    itemImage.set("image", nftToSend.image);

    itemImage.set("nftContract", nftToSend.token_address);

    itemImage.set("tokenId", nftToSend.token_id);

    itemImage.set("name", nftToSend.name);

    itemImage.save();

  }

  return (

    <>

      <div style={styles.NFTs}>

        {contractABIJson.noContractDeployed && (

          <>

            <Alert

              message="No Smart Contract Details Provided. Please deploy smart contract and provide address + ABI in the MoralisDappProvider.js file"

              type="error"

            />

            <div style={{ marginBottom: "10px" }}></div>

          </>

        )}

        {!fetchSuccess && (

          <>

            <Alert

              message="Unable to fetch all NFT metadata... We are searching for a solution, please try again later!"

              type="warning"

            />

            <div style={{ marginBottom: "10px" }}></div>

          </>

        )}

        {NFTBalance &&

          NFTBalance.map((nft, index) => (

            <Card

             key={index}

              hoverable

              actions={[

                <Tooltip title="View On Blockexplorer" key={index}>

                  <FileSearchOutlined

                  key={index}

                    onClick={() =>

                      window.open(

                        `${getExplorer(chainId)}address/${nft.token_address}`,

                        "_blank"

                      )

                    }

                  />

                </Tooltip>,

                <Tooltip title="List NFT for sale" key={index}>

                  <ShoppingCartOutlined onClick={() => handleSellClick(nft)} key={index}/>

                </Tooltip>,

              ]}

              style={{ width: 240, border: "2px solid #e7eaf3" }}

              cover={

                <Image

                key={index}

                  preview={false}

                  src={nft?.image || "error"}

                  fallback="data:image/png;base64,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"

                  alt=""

                  style={{ height: "240px" }}

                />

              }

            >

              <Meta title={nft.name} description={nft.contract_type} key={index} />

            </Card>

          ))}

      </div>

     

      <Modal

       

        title={`List ${nftToSend?.name} #${nftToSend?.token_id} For Sale`}

        visible={visible}

        onCancel={() => setVisibility(false)}

        onOk={() => list(nftToSend, price)}

        okText="List"

       

        footer={[

          <Button onClick={() => setVisibility(false)}>

            Cancel

          </Button>,

          <Button onClick={() => approveAll(nftToSend)} type="primary">

            Approve

          </Button>,

          <Button onClick={() => list(nftToSend, price)} type="primary">

            List

          </Button>

        ]}

      >

        <Spin spinning={loading}>

          <img

            src={`${nftToSend?.image}`}

            style={{

              width: "250px",

              margin: "auto",

              borderRadius: "10px",

              marginBottom: "15px",

            }}

          />

          <Input

            autoFocus

            placeholder="Listing Price in MATIC"

            onChange={(e) => setPrice(e.target.value)}

          />

        </Spin>

      </Modal>

    </>

  );

}

export default NFTBalance;

NFTMarketTransactions

import React, { useState } from "react";

import { useMoralis, useMoralisQuery } from "react-moralis";

import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";

import { Table, Tag, Space } from "antd";

import { PolygonCurrency} from "./Chains/Logos";

import moment from "moment";

const styles = {

  table: {

    margin: "0 auto",

    width: "1000px",

  },

};

function NFTMarketTransactions() {

  const { walletAddress } = useMoralisDapp();

  const { Moralis } = useMoralis();

  const queryItemImages = useMoralisQuery("ItemImages");

  const fetchItemImages = JSON.parse(

    JSON.stringify(queryItemImages.data, [

      "nftContract",

      "tokenId",

      "name",

      "image",

    ])

  );

  const queryMarketItems = useMoralisQuery("MarketItems");

  const fetchMarketItems = JSON.parse(

    JSON.stringify(queryMarketItems.data, [

      "updatedAt",

      "price",

      "nftContract",

      "itemId",

      "sold",

      "tokenId",

      "seller",

      "owner",

    ])

  )

    .filter(

      (item) => item.seller === walletAddress || item.owner === walletAddress

    )

    .sort((a, b) =>

      a.updatedAt < b.updatedAt ? 1 : b.updatedAt < a.updatedAt ? -1 : 0

    );

  function getImage(addrs, id) {

    const img = fetchItemImages.find(

      (element) =>

        element.nftContract === addrs &&

        element.tokenId === id

    );

    return img?.image;

  }

  function getName(addrs, id) {

    const nme = fetchItemImages.find(

      (element) =>

        element.nftContract === addrs &&

        element.tokenId === id

    );

    return nme?.name;

  }

  const columns = [

    {

      title: "Date",

      dataIndex: "date",

      key: "date",

    },

    {

      title: "Item",

      key: "item",

      render: (text, record) => (

        <Space size="middle">

          <img src={getImage(record.collection, record.item)} style={{ width: "40px", borderRadius:"4px"}} />

          <span>#{record.item}</span>

        </Space>

      ),

    },

    {

      title: "Collection",

      key: "collection",

      render: (text, record) => (

        <Space size="middle">

          <span>{getName(record.collection, record.item)}</span>

        </Space>

      ),

    },

    {

      title: "Transaction Status",

      key: "tags",

      dataIndex: "tags",

      render: (tags) => (

        <>

          {tags.map((tag) => {

            let color = "geekblue";

            let status = "BUY";

            if (tag === false) {

              color = "volcano";

              status = "waiting";

            } else if (tag === true) {

              color = "green";

              status = "confirmed";

            }

            if (tag === walletAddress) {

              status = "SELL";

            }

            return (

              <Tag color={color} key={tag}>

                {status.toUpperCase()}

              </Tag>

            );

          })}

        </>

      ),

    },

    {

      title: "Price",

      key: "price",

      dataIndex: "price",

      render: (e) => (

        <Space size="middle">

          <PolygonCurrency/>

          <span>{e}</span>

        </Space>

      ),

    }

  ];

  const data = fetchMarketItems?.map((item, index) => ({

    key: index,

    date: moment(item.updatedAt).format("DD-MM-YYYY HH:mm"),

    collection: item.nftContract,

    item: item.tokenId,

    tags: [item.seller, item.sold],

    price: item.price / ("1e" + 18)

  }));

  return (

    <>

      <div>

        <div style={styles.table}>

          <Table columns={columns} dataSource={data} />

        </div>

      </div>

    </>

  );

}

export default NFTMarketTransactions;

const columns = [

  {

    title: "Date",

    dataIndex: "date",

    key: "date",

  },

  {

    title: "Item",

    key: "item",

  },

  {

    title: "Collection",

    key: "collection",

  },

  {

    title: "Transaction Status",

    key: "tags",

    dataIndex: "tags",

  },

  {

    title: "Price",

    key: "price",

    dataIndex: "price",

  }

];

App.jsx

import { useEffect, useState} from "react";

import { useMoralis } from "react-moralis";

import {

  BrowserRouter as Router,

  Switch,

  Route,

  NavLink,

  Redirect,

} from "react-router-dom";

import Account from "components/Account";

import Chains from "components/Chains";

import NFTBalance from "components/NFTBalance";

import NFTTokenIds from "components/NFTTokenIds";

import { Menu, Layout} from "antd";

import SearchCollections from "components/SearchCollections";

import "antd/dist/antd.css";

import NativeBalance from "components/NativeBalance";

import "./style.css";

import Text from "antd/lib/typography/Text";

import NFTMarketTransactions from "components/NFTMarketTransactions";

const { Header, Footer } = Layout;

const styles = {

  content: {

    display: "flex",

    justifyContent: "center",

    fontFamily: "Roboto, sans-serif",

    color: "#041836",

    marginTop: "130px",

    padding: "10px",

  },

  header: {

    position: "fixed",

    zIndex: 1,

    width: "100%",

    background: "#fff",

    display: "flex",

    justifyContent: "space-between",

    alignItems: "center",

    fontFamily: "Roboto, sans-serif",

    borderBottom: "2px solid rgba(0, 0, 0, 0.06)",

    padding: "0 10px",

    boxShadow: "0 1px 10px rgb(151 164 175 / 10%)",

  },

  headerRight: {

    display: "flex",

    gap: "20px",

    alignItems: "center",

    fontSize: "15px",

    fontWeight: "600",

  },

};

const App = ({ isServerInfo }) => {

  const { isWeb3Enabled, enableWeb3, isAuthenticated, isWeb3EnableLoading } =

    useMoralis();

  const [inputValue, setInputValue] = useState("explore");

  useEffect(() => {

    if (isAuthenticated && !isWeb3Enabled && !isWeb3EnableLoading) enableWeb3();

    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, [isAuthenticated, isWeb3Enabled]);

  return (

    <Layout style={{ height: "100vh", overflow: "auto" }}>

      <Router>

        <Header style={styles.header}>

          <Logo />

          <SearchCollections setInputValue={setInputValue}/>

          <Menu

            theme="light"

            mode="horizontal"

            style={{

              display: "flex",

              fontSize: "17px",

              fontWeight: "500",

              marginLeft: "50px",

              width: "100%",

            }}

            defaultSelectedKeys={["nftMarket"]}

          >

            <Menu.Item key="nftMarket" onClick={() => setInputValue("explore")} >

              <NavLink to="/NFTMarketPlace">🛒 Explore Market</NavLink>

            </Menu.Item>

            <Menu.Item key="nft">

              <NavLink to="/nftBalance">🖼 Your Collection</NavLink>

            </Menu.Item>

            <Menu.Item key="transactions">

              <NavLink to="/Transactions">📑 Your Transactions</NavLink>

            </Menu.Item>

          </Menu>

          <div style={styles.headerRight}>

            <Chains />

            <NativeBalance />

            <Account />

          </div>

        </Header>

        <div style={styles.content}>

          <Switch>

            <Route path="/nftBalance">

           <NFTBalance key={"nftbalance"}/>

            </Route>

            <Route path="/NFTMarketPlace">

              <NFTTokenIds inputValue={inputValue} setInputValue={setInputValue}/>

            </Route>

            <Route path="/Transactions">

              <NFTMarketTransactions />

            </Route>

          </Switch>

          <Redirect to="/NFTMarketPlace" />

        </div>

      </Router>

      <Footer style={{ textAlign: "center" }}>

        <Text style={{ display: "block" }}>

          ⭐️ Please star this{" "}

          <a

            href="https://github.com/ethereum-boilerplate/ethereum-boilerplate/"

            target="_blank"

            rel="noopener noreferrer"

          >

            boilerplate

          </a>

          , every star makes us very happy!

        </Text>

        <Text style={{ display: "block" }}>

          🙋 You have questions? Ask them on the {""}

          <a

            target="_blank"

            rel="noopener noreferrer"

            href="https://forum.moralis.io/t/ethereum-boilerplate-questions/3951/29"

          >

            Moralis forum

          </a>

        </Text>

        <Text style={{ display: "block" }}>

          📖 Read more about{" "}

          <a

            target="_blank"

            rel="noopener noreferrer"

            href="https://moralis.io?utm_source=boilerplatehosted&utm_medium=todo&utm_campaign=ethereum-boilerplat"

          >

            Moralis

          </a>

        </Text>

      </Footer>

    </Layout>

  );

};

export const Logo = () => (

  <div style={{ display: "flex" }}>

    <svg

      width="60"

      height="38"

      viewBox="0 0 50 38"

      fill="none"

      xmlns="http://www.w3.org/2000/svg"

    >

      <path

        d="M43.6871 32.3986C43.5973 32.4884 43.53 32.5782 43.4402 32.6905C43.53 32.6007 43.5973 32.5109 43.6871 32.3986Z"

        fill="black"

      />

      <path

        d="M49.7037 14.3715C49.5241 6.2447 42.7891 -0.17592 34.6624 0.00367768C31.0031 0.0934765 27.4784 1.53026 24.8294 4.06708C22.113 1.46291 18.4986 0.00367768 14.727 0.00367768C6.71246 0.00367768 0.202047 6.49164 0 14.5511V14.6633C0 20.8146 2.24497 26.2698 4.26545 30.0189C5.11853 31.5904 6.08387 33.117 7.13901 34.5762C7.5431 35.115 7.8574 35.564 8.10435 35.8559L8.39619 36.2151L8.48599 36.3273L8.50844 36.3498L8.53089 36.3722C10.2146 38.3253 13.1555 38.5498 15.1087 36.8886C15.1311 36.8661 15.1536 36.8437 15.176 36.8212C17.1291 35.0701 17.3312 32.0843 15.625 30.1087L15.6026 30.0638L15.423 29.8618C15.2658 29.6597 15.0189 29.3455 14.727 28.9414C13.9188 27.8189 13.178 26.6515 12.5269 25.4392C10.8881 22.4309 9.42888 18.6145 9.42888 14.7531C9.49623 11.8347 11.9432 9.52236 14.8617 9.58971C17.7128 9.65705 19.9802 11.9694 20.0251 14.8205C20.0476 15.5389 20.2272 16.2348 20.5415 16.8859C21.4844 19.3104 24.2232 20.5227 26.6478 19.5798C28.4438 18.8839 29.6336 17.1553 29.6561 15.2246V14.596C29.7683 11.6775 32.2153 9.38766 35.1562 9.47746C37.94 9.56726 40.1625 11.8122 40.2748 14.596C40.2523 17.6941 39.2645 20.7472 38.1421 23.1718C37.6931 24.1371 37.1992 25.08 36.6379 25.978C36.4359 26.3147 36.2787 26.5617 36.1665 26.6964C36.1216 26.7862 36.0767 26.8311 36.0542 26.8535L36.0318 26.876L35.9869 26.9433C37.6033 24.9004 40.5442 24.5412 42.5871 26.1576C44.4953 27.6617 44.9443 30.3781 43.6198 32.4211L43.6422 32.4435V32.3986L43.6647 32.3762L43.732 32.2864C43.7769 32.1966 43.8667 32.1068 43.9565 31.9721C44.1361 31.7027 44.3606 31.3435 44.6525 30.8945C45.3933 29.6822 46.0668 28.4026 46.673 27.1229C48.1097 24.0249 49.6812 19.5349 49.6812 14.5286L49.7037 14.3715Z"

        fill="#041836"

      />

      <path

        d="M39.7135 25.1249C37.1094 25.1025 34.9991 27.2127 34.9766 29.8169C34.9542 32.4211 37.0645 34.5313 39.6686 34.5538C41.1503 34.5538 42.5647 33.8578 43.4626 32.6905C43.53 32.6007 43.5973 32.4884 43.6871 32.3986C45.1015 30.221 44.4729 27.3025 42.2953 25.9107C41.532 25.3943 40.634 25.1249 39.7135 25.1249Z"

        fill="#B7E803"

      />

    </svg>

  </div>

);

export default App;

I just redeployed the contract to Mumbai and put the new market address in my code and nothing has changed on my Dapp after I refreshed it a few times and tried listing a NFT. Something must be throwing the error, correct? Should i start commenting things out and try isolate the error from somewhere or am I missing something that throws that error?
:slight_smile:

Just a idea I wanted to ask.
Is there anyone on the Moralis Team who can go through the code completely and help find a solution aswell as updating the repo? :slight_smile: )
Cheers

@alex
Here is my github repo to my code

Hi @KyeG

I just wanted to let you know that I’m aware of the general programming principle you mentioned. I have tried to solve same issue in my application, but it keeps causing the app to stop working, leading to numerous errors. I will persist in resolving this issue. So, I recommended you to take help from some of the best Marketplace development company like Shiv Technolabs.

Thank you so much for your continued assistance.