I have a nftToken Contract that mints token to msg.sender, then I have a function in a market contract that transfers the nft from owner to market contract. However, I am getting an error that says: ERC721: transfer caller is not owner nor approved.
here is my nftContract (nft) function snippet:
function createToken(string memory tokenURI) public returns (uint) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(msg.sender, newItemId); _setTokenURI(newItemId, tokenURI); setApprovalForAll(contractAddress, true); return newItemId; } here is my market code (stripeMarket Contract) function snippet:
function createItem( address nftContract, uint256 tokenId ) public payable{ address _owner = IERC721(nftContract).ownerOf(tokenId); IERC721(nftContract).transferFrom(_owner, address(this),tokenId); IERC721(nftContract).approve(address(this),tokenId); } and here I am trying to call it from the frontend with web3:
const getItems=async()=>{ await contracts.nft.methods.createToken("").send({from: accounts[0]}); const owners = await contracts.nft.methods.ownerOf(1).call({from:accounts[0]}); await contracts.stripeMarket.methods.createItem(contracts.nft._address,1).send({from: {owners}}); } But I am getting error. Any help is appreciated, thanks!
1 Answer
When the nftContract executes the setApprovalForAll(contractAddress, true), it allows the contractAddress (the Market contract) to operate all of the nftContract's tokens.
But the newly minted token is owned by the msg.sender - not by the nftContract. So the approval does not apply to this token.
Depending on your use case, you can
Mint the new token to the
nftContract(instead of themsg.sender) so that the Market contract is allowed to operate it. Or mint it to the Market contract directly.// the owner is the `nftContract` _mint(address(this), newItemId); // the Market contract is allowed to operate the `nftContract`'s tokens setApprovalForAll(contractAddress, true);Have the
msg.sender(the token owner) executeapprove(marketAddress, tokenId)on thenftContractbefore executing thecreateItem().This will give the Market contract approval to operate this particular token owned by the
msg.sender. (Assuming it's the same address as the_owner- otherwise it will fail.)