Burn an existing NFT and Mint a new NFT in one go

I am developing a Dapp for NFT minting. In order to mint a new 2nd NFT, the user has to burn the 1st one that he owns. I know that our Dapp can prompt the user to burn the 1st NFT. And only after it's successful, it can prompt him/her to mint the 2nd NFT.

But it's there a way to improve the UX by prompting the user once only?

I tried to use smart contract B (for 2nd NFT) to call smart contract A (for 1st NFT)'s burn function. But in order to do that, user needs to "approve" contractB to contractA (i.e. authorize contractB to burn 1st NFT on user's behalf). And that results in prompting the user to perform this "approve" action. (prompting user twice in total).

Any suggestion? Thanks.

  1. Create contract X
  2. Create a function which
    a) Receives user's 1st NFT, then call burn in contract A (contract X will be the owner of 1st NFT now, so contract X can call burn in contract A no approve required)
    b) Now call Mint in contract B and receive 2nd NFT in contract X
    c) Now Transfer the 2nd NFT to user's address
    You can do all three steps in one function.

@Keerthana_Ramalingam such a brilliant idea. Thanks.

For 2a, does it mean that Contract X needs to call the "safeTransferFrom" function of Contract A to transfer the ownership of NFT from the contract caller to Contract X?

Also, i read from some articles that such Contract X needs to implement the "IERC721Receiver" interface and return "Solidity selector". Seems a bit complicated to me. If you can show me some example codes, that would be much appreciated.

To be able to do something like that your smart contract has to implement onERC721Received (and the nft contract has to support that) and on receiving the token it will have to execute your logic to burn the token directly and then mint the new token.

Keep in mind this will trigger when someone transfers the nft to your contract. You however can’t control how that happens. You won’t for example be able to say hey do this when someone first transfers xx eth to me.

Those are however restrictions in place if the original NFT smart contract is not controlled by you.
If you do control the first nft contract you can add a function that allows your dApp contract to transfer the NFT’s and then just call call a function in your smart contract that does the burning and minting.

// SPDX-License-Identifier: UNLICENSED
// NOT A PRODUCTION CODE - NO TESTING DONE - MADE ONLY FOR REFERENCE
pragma solidity ^0.8.2;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";

contract X {

    //Make sure to call "safeTransferFrom" in contract A for NFT_ID_OF_contractA
    function testTransfer(address contractA, address contractB, uint NFT_ID_OF_contractA, uint NFT_ID_OF_contractB) public {
        IERC721(contractA).safeTransferFrom(msg.sender, address(this),NFT_ID_OF_contractA);
        IERC721(contractA).burn(NFT_ID_OF_contractA); //Create custom interface for using Burn
        IERC721(contractB).mint(NFT_ID_OF_contractB); //Create custom interface for using Mint
    }

    // This to make sure contract X receives ERC721 tokens via safeTransferFrom
    function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
        return IERC721Receiver.onERC721Received.selector;
    }
}