Cloning OpenSea NFT Boilerplate Questions

Capture dā€™Ć©cran 2022-06-09 015626

Do I need to put this code in before I create ItemImage in the dashboard?

No, I just did that as a test on my end. It just simply saves a random object to ItemImages.

Ok serā€¦ What is the type class? Capture dā€™Ć©cran 2022-06-09 015932

Custom as you have to name it ItemImages.

1 Like

You are The best serā€¦!!!

Great. Maybe you can try with another server later as a test to see why it wasnā€™t creating automatically.

Any progress on this yet?

Yes I will make another server laterā€¦ Now I need to integrate a minting dapp because I already have one that works well but I would like to put everything on my marketplaceā€¦

And i see that moralis tutorials are only in ERC1155ā€¦ personally i prefer ERC721 with a random mint functionā€¦

I will post any examples when finished. There are a few complications that come with larger collections.

Thank you, appreciate the help. Im not sure if loading the entire collection is necessary, but there definitely needs to be some way to sort or filter the items, especially ones that are up for sale.

Some of the tutorials also cover ERC721 e.g. How to Create Own NFT (Using Moralis).

This is a basic rough example, but good enough to get started.

1: Sync NFT contract results from getAllTokenIds into a Class

This code uses this example which loops through all of the NFTs and syncs each one as an Object to the Class (bulkWrite may be better here). It would make sense to use separate Classes for each collection. To test, you can run this code in the frontend - but it should be done in a backend or Cloud Function.

const Sync = Moralis.Object.extend('CollectionName');

let cursor = null;

do {
  const response = await Moralis.Web3API.token.getAllTokenIds({
    address: '0x51790d397e3cc5f418635796e75c8b58ea113f3d', 
    chain: 'polygon',
    cursor,
  });
  
  // for each NFT, sync each to the Sync table
  for (const nft of response.result) {
    const sync = new Sync();
    
    // Issue of numbers as strings not being sortable from DB, workaround is to save token_id as a number
    sync.set({
      ...nft,
      token_id: Number(nft.token_id),
    });

    sync.save();
  }

  cursor = response.cursor;

} while (cursor !== '' && cursor != null);

2: Query this data in hooks\useNFTTokenIds.js

The fetch uses getNFTTokenIds which is used already so the rest of the hook doesnā€™t need to be changed.


// remove : getNFTTokenIds from old getAllTokenIds fetch
const { fetch: getNFTTokenIds, data } = useMoralisQuery(
  'CollectionName',
  (query) => query.descending('token_id') // ascending available
);

useEffect(() => {
  async function run() {
    // create deep clone of flattened data so is similar to API response structure
    const NFTs = JSON.parse(JSON.stringify(data.map(({ attributes }) => attributes)));

    // same code from existing useEffect
    // setTotalNFTs(); // we don't have a total now, you can get it yourself from getAllTokenIds
    setFetchSuccess(true);
    for (let NFT of NFTs) {
      if (NFT?.metadata) {
        NFT.metadata = JSON.parse(NFT.metadata);
        NFT.image = resolveLink(NFT.metadata?.image);
      } else if (NFT?.token_uri) {
        try {
          await fetch(NFT.token_uri)
            .then((response) => response.json())
            .then((data) => {
              NFT.image = resolveLink(data.image);
            });
        } catch (error) {
          setFetchSuccess(false);
        }
      }
    }
    setNFTTokenIds(NFTs);
  }

  if (data) {
    run();
  }

}, [data]);

// comment out other useEffect

3: Use new data source in components\NFTTokenIds.jsx

Fetch MarketItems data.

const { fetch, data } = useMoralisQuery('MarketItems');

Set up filter function:

// use existing NFTTokenIds data from the hook as initial state
const [filteredNFTs, setFilteredNFTs] = useState(NFTTokenIds);

function filterHandler(e) {

  const marketItems = data.map(({ attributes }) => attributes); // flatten

  if (e.target.checked) { // if checkbox is ticked

	// filter results based on matching token_address and token_id
    const filtered = NFTTokenIds.filter((token) => {

      return marketItems.some((marketItem) => {
        return (
          marketItem.nftContract === token.token_address &&
          marketItem.tokenId === String(token.token_id)
        );
      });

    });

    setFilteredNFTs(filtered);
  } else {
    setFilteredNFTs(NFTTokenIds);
  }
}

Map over the new state instead of NFTTokenIds:

{inputValue !== 'explore' &&
filteredNFTs.map((nft, index) => (
...

Then set up the checkbox to test the filter.

<label htmlFor="sale">For sale</label>
<input type="checkbox" id="sale" onChange={(e) => filterHandler(e)} />

...
{contractABIJson.noContractDeployed && (

Notes:

This example uses static addresses, names, etc. so you will need to change things appropriately for multiple collections.

For a large collection (this one used 25,000 so 3-5 minutes), it will take some time to sync. And it may error out, so you have to handle that - you could do length checks of the DB vs the total given by getAllTokenIds.

If you want people adding their own collections to your site you will have to factor in potential simultaneous API calls to get the NFT data - upgrade your plan for a higher API limit or pay for a custom limit.

If you run into this issue for testing from your app Too many requests to Web3 API from this particular client, adjust your rate limits.

You can implement pagination so users can go over more pages of NFTs.

Thank you for the information. Im not familiar with how to do most of what you said, but I will do my best to try to figure it out. What exactly would implementing all of this do? Not sure what the result of all this would give me? Having these elements would be ideal:

Getting the search by name or attribute & filter by price low to high are the first 2 concerns. Then adding the information about items, owners, floor price & total volume. Maybe just in the section where the collection size data is rendered in the boilerplate?

Really just need these 3 things in that order & ill be ready to launch. I will launch with just 1 &/or 2 completed if option 3 is hard to do to start. Is that what your example would do?

So Iā€™ve copied the Etherium Boilerplate and started going through the tutorial. However it looks to be somewhat different than whatā€™s on the YouTube tutorial. Did I copy the right Eth boilerplate?

ethereum nft marketplace boilerplate is the correct one to copy.

1 Like

Thanks but Iā€™ve already seen this one. He talks about creating his nftā€¦ I already have my contract which contains 200 nft ready to be minted by peopleā€¦ :yum:

Hey is anyone getting. this error

src/components/AddressInput.jsx
Line 14:6: React Hook useEffect has missing dependencies: ā€˜propsā€™ and ā€˜validatedAddressā€™. Either include them or remove the dependency array. However, ā€˜propsā€™ will change when any prop changes, so the preferred fix is to destructure the ā€˜propsā€™ object outside of the useEffect call and refer to those specific props inside useEffect react-hooks/exhaustive-deps

My dapp was working then this error popped up, any solutions?
Thanks guys

Your app should still work despite that warning, you can ignore this for now. You may need to reload the page.