I am trying to build an dApp that allows users to transfer their ERC721 token to my smart contract, and then at a later time, send to another user. Here is my contract code:
contract HoldNFT is ERC721, IERC721Receiver, ERC721Holder, Ownable{
using Counters for Counters.Counter;
Counters.Counter public _tokenIDs;
constructor() ERC721("HoldNFT", "HOLDNFT") {
_tokenIDs.increment();
}
function send(IERC721 tokenAddress, uint256 tokenId) public {
uint256 current = _tokenIDs.current();
tokenAddress.safeTransferFrom(msg.sender, address(this), tokenId);
_safeMint(recipient, current);
_tokenIDs.increment();
}
}
When I call on this function, I get the errow message "Revert ERC721: transfer caller is not owner or approved". My understanding is that this occurs because I am calling the safeTransferFrom function from a smart contract, so the msg.sender in the IERC721 contract (tokenAddress argument) is my smart contract instead of the user, who actually owns the token. I want to know if there is a way around this. I know that you can call the safeTransferFrom function or approve function from JavaScript so the msg.sender is the user. However, I don't think this will work in my particular case because the tokenAddress is arbitary (decided by the user) so I do not have access to the ABI in development. What should I do?
P.S. The template I used for this project was from a dApp called nftysanta (0x1f4E4eF54dB90934DE8fB2d68438C68660099Ad4). It seems to use the same implementation as far as I can see? And I assumed that it works because it's a verified contract on mainnet.