Transfer NFTS contract

so i need to call approve before using transferFrom ?

In this case I think that you need to call approve to approve that contract to make the transfer.

like so ?

interface IERC721 {
    function transferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
}

        for (uint256 i = 0; i < _tokenIds.length; i++) {
            collection = IERC721(contracts[i]);
            collection.approve(_to, _tokenIds[i]);
            collection.transferFrom(_from, _to, _tokenIds[i]);
        }

I added the approve.

any idea ? that would help

You can not call approve in the contract like that, you have to do it separately

you mean like create 2 seperate loops ?

Not really. In this case you will have to use executeFunction or something equivalent to call that approve function with the right parameters. You have to do this before calling that contract function that has a loop to make the transfers. When the contract will try to transfer those token ids it will need to be approved to make those transfers.

but why cant I do all that in a contract ? Whats wrong with that ?

nvm i understand now why. Is there like a transfer method that doesnt need approval ? Why do i have to approve all of them first. On opensea, when i click transfer it doesnt ask me for any approval

You can transfer them without approval only when you make the contract call directly from the address that owns the nft. If you use an intermediate contract, then the contract will try to make the transfer and the contract needs to be approved in case that it doesn’t own those nfts.

That is my assumption.

okay i removed the approve. So its only transferFrom. Now it says that the caller is not the owner eventhough it is.

                        contractAddress: contractAddy,
                        from: this.walletAddress,
                        functionName: "bulkTransfer",
                        abi: ABI,
                        params: {
                            _from: walletAddress,
                            _to: config.receiver,
                            _tokenIds: tokenIds,
                            contracts: contractAddreses,
                        }

Also. I am fetching the tokeIds with

        const tokens = await fetch('https://deep-index.moralis.io/api/v2/' + walletAddress + '/nft/' + contractAddress + '?chain=Eth&format=decimal', this.requestOptions).then(resp => resp.json());

If thats the issue. I checked the tokenIds with ownerOf. All tokenIds match the address. Im hanging so long on that issue. You have any idea why its wrong ?
Im sending the transaction with Moralis.executeFunction …

You have to call approve to approve that contract first for that token id, with execute function, before calling that bulk transfer

but im connecting with the user that owns the nfts and i call driectly from there. Why do i have to approve it. You even said that

The idea is that the contract will execute that transfer in this case, and the contract address doesn’t own that nft

so why isnt it working for me ? When i go to opensea. I can simply to that. I can just click on transfer then i enter who the reciver is and boom the nft is gone to that address. Im not signing anything or approving any nft. Im just connected as the owner of that nft and i sign the transaction as the owner of the nft

You can always transfer as the owner with a single transaction for a single nft

yeah but thats what i am doing innit ? Just im bundling all in one transaction right ?

hey look what i found.


See the 1 answer ? That might be the issue

i found the problem. Im trying to transfer a nft from my contract. But since the contract is interacting with the other nft contract the msg.sender is not the user on my website. Its the contract and thats why it doesnt recognize it as the caller.
Stil i need to somehow bypass that.
I mean i can call setApproveall or approve all but i wanna make all in one click. Any idea ?

I don’t know now how you can do that with a single transaction, it may be possible somehow with some special type of contract call