Cloning OpenSea NFT Boilerplate Questions

For sure @Crypto! This is a boilerplate meant to spark your imagination and you can build anything like that on top of this boilerplate :+1:

Please anyone help me to know where smart contract address do i get?

and Can i test it like that above you did in Youtube?

Hi, firstly really appreciate what you have done for the community. I’m studying to become a blockchain developer and your video is really helpful to me. I have a question when setting up the project on local: How can I have some NFT on my address on testnet like you in the video? Currently I don’t have any so I cannot list anything, I cannot buy anything as well since all items are not for sale. Thank you in advance.

Hey @lion33, you can deploy the smart contract yourself. It is provided in the repository, so simply just deploy with Remix or Hardhat what ever you feel comfortable with. Then you can get the smart contract address and ABI :slight_smile:

As long as you have some NFTs in the network you deploy the smart contract to, you should the also be able to test out the sell and buy functionality.

1 Like

Glad you are enjoying Moralis @vantueyeude!

You can have a look at how to deploy a very simple ERC721 NFT collection yourself, just generate some metadata and images, store it on IPFS and then mint the collection to your own address. Then the NFTs should be available in the “Your Collection” tab in the dApp!

This video on the Moralis Youtube channel could be a nice starting point:

Hi, thanks for the tutorial! I am currently following the tutorial but have noticed that the chainId and walletAddress are undefined. Do I need something like metamask to have these values be defined?

I have a question regarding retrieving NFTs from collections using getAllTokenIds(). I am attempting to load a limited number of items from a collection on initial render so I retrieve N number of NFTsfrom a collection on initial load and give the user an option to load more when they reach the bottom of the page. (See image) I must be misunderstanding the offset parameter in the getAllTokenIds() as I assumed if I adjust my offset on every call with my previous count I should be fetching from where I left off but this does not seem to be the case as I am getting duplicates. How does this offset parameter work behind the scenes.


hi ulvur, have you solve this approval problem yet? i encounter a problem "Fail with error ‘ERC721: transfer caller is not owner nor approved’.

Hello! yes, you should implement de ERC721Receiver on your Smart Contract

Check it out:

You are probably having same issue as answered below :slight_smile:
Also check that the Smart Contract is approved by the NFT’s Contract using approvedByAll() or something like that

1 Like

That is very nice functionality to add @ifelse ,

I think at the moment the way the NFTs are indexed when using getAllTokenIds() doesn’t return the collection in the same order every time. So if you make multiple calls, even though you are offsetting, it might return duplicates.

Maybe you could retrieve the whole collection or large N value of NFT’s in the initial call and then only render them if the user reaches the bottom of the page. Or then add functionality where the user can select how many (N = ?) NFTs they wish to browse.

Yup @ZeusExMachina,

Just getting the MetaMask plugin on your browser and creating an account should get you going and able to authenticate to the dApp.

1 Like

Hello I am at the 56 minute mark and when i change the nftbalance file to add the const and i follow instructions to the letter i end up with the local host throwing a ton of errors, what am i missing?

this only happens when i add

const contractProcessor = useWeb3ExecuteFunction();

const contractABIJson = JSON.parse(contractABI);

Hi @mikeze!

This error might be thrown because you are trying to JSON.parse() the contractABI, when it’s not provided or improperly formatted.

Could you check that you are bringing in contractABI using useMoralisDapp() and that everything is inline in the MoralisDappProvider.js file, as shown in the screenshots below :slight_smile:

It appears to be exactly as shown… not sure whatelse to check

Oh thats unfortunate… I still have a feeling it will be something to do with the contractABI, could you send over your contractABI from MoralisDappProvider.js line 9?

You could even try some very simple string in the mean while, instead of the ABI on line 9 like:

'{"foo": "bar"}'

const [contractABI, setContractABI] = useState(’[ { “inputs”: [], “stateMutability”: “nonpayable”, “type”: “constructor” }, { “anonymous”: false, “inputs”: [ { “indexed”: true, “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “indexed”: true, “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “indexed”: true, “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “indexed”: false, “internalType”: “address”, “name”: “seller”, “type”: “address” }, { “indexed”: false, “internalType”: “address”, “name”: “owner”, “type”: “address” }, { “indexed”: false, “internalType”: “uint256”, “name”: “price”, “type”: “uint256” }, { “indexed”: false, “internalType”: “bool”, “name”: “sold”, “type”: “bool” } ], “name”: “MarketItemCreated”, “type”: “event” }, { “anonymous”: false, “inputs”: [ { “indexed”: true, “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “indexed”: false, “internalType”: “address”, “name”: “owner”, “type”: “address” } ], “name”: “MarketItemSold”, “type”: “event” }, { “inputs”: [ { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “internalType”: “uint256”, “name”: “price”, “type”: “uint256” } ], “name”: “createMarketItem”, “outputs”: [], “stateMutability”: “payable”, “type”: “function” }, { “inputs”: [ { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” } ], “name”: “createMarketSale”, “outputs”: [], “stateMutability”: “payable”, “type”: “function” }, { “inputs”: [], “name”: “fetchMarketItems”, “outputs”: [ { “components”: [ { “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “internalType”: “address payable”, “name”: “seller”, “type”: “address” }, { “internalType”: “address payable”, “name”: “owner”, “type”: “address” }, { “internalType”: “uint256”, “name”: “price”, “type”: “uint256” }, { “internalType”: “bool”, “name”: “sold”, “type”: “bool” } ], “internalType”: “struct OHMarketplace.MarketItem[]”, “name”: “”, “type”: “tuple[]” } ], “stateMutability”: “view”, “type”: “function” }, { “inputs”: [], “name”: “owner”, “outputs”: [ { “internalType”: “address”, “name”: “”, “type”: “address” } ], “stateMutability”: “view”, “type”: “function” } ] }’)

ah ok got it! I Have another question regarding the existing collections? When I click on the shopping cart all the existing collections are not for sale. Is it possible to make offers on these items like opensea has on some items or is this something opensea does internally and would need to use their sdk for this functionality?

Seems like you have an extra squiggly bracket at the end of your string @mikeze,

This works on my end, so could you try pasting this into you DappProvider and see if it works :slight_smile:

const [contractABI, setContractABI] = useState('[ { “inputs”: [], “stateMutability”: “nonpayable”, “type”: “constructor” }, { “anonymous”: false, “inputs”: [ { “indexed”: true, “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “indexed”: true, “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “indexed”: true, “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “indexed”: false, “internalType”: “address”, “name”: “seller”, “type”: “address” }, { “indexed”: false, “internalType”: “address”, “name”: “owner”, “type”: “address” }, { “indexed”: false, “internalType”: “uint256”, “name”: “price”, “type”: “uint256” }, { “indexed”: false, “internalType”: “bool”, “name”: “sold”, “type”: “bool” } ], “name”: “MarketItemCreated”, “type”: “event” }, { “anonymous”: false, “inputs”: [ { “indexed”: true, “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “indexed”: false, “internalType”: “address”, “name”: “owner”, “type”: “address” } ], “name”: “MarketItemSold”, “type”: “event” }, { “inputs”: [ { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “internalType”: “uint256”, “name”: “price”, “type”: “uint256” } ], “name”: “createMarketItem”, “outputs”: [], “stateMutability”: “payable”, “type”: “function” }, { “inputs”: [ { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” } ], “name”: “createMarketSale”, “outputs”: [], “stateMutability”: “payable”, “type”: “function” }, { “inputs”: [], “name”: “fetchMarketItems”, “outputs”: [ { “components”: [ { “internalType”: “uint256”, “name”: “itemId”, “type”: “uint256” }, { “internalType”: “address”, “name”: “nftContract”, “type”: “address” }, { “internalType”: “uint256”, “name”: “tokenId”, “type”: “uint256” }, { “internalType”: “address payable”, “name”: “seller”, “type”: “address” }, { “internalType”: “address payable”, “name”: “owner”, “type”: “address” }, { “internalType”: “uint256”, “name”: “price”, “type”: “uint256” }, { “internalType”: “bool”, “name”: “sold”, “type”: “bool” } ], “internalType”: “struct OHMarketplace.MarketItem[]”, “name”: “”, “type”: “tuple[]” } ], “stateMutability”: “view”, “type”: “function” }, { “inputs”: [], “name”: “owner”, “outputs”: [ { “internalType”: “address”, “name”: “”, “type”: “address” } ], “stateMutability”: “view”, “type”: “function”}]');