NFT Metadata URL not being sent from source chain to destination chain using Chainlink's CCIP

39 views Asked by At

I am implementing this article from Chainlink on how to mint NFTs across blockchains. https://andrej-rakic.gitbook.io/chainlink-ccip/ccip-masterclass/exercise-2-transfer-tokens-and-data

In the tutorial, they are hard coding the IPFS NFT Metadata URL into the MyNFT contract on the destination chain.

I want to allow users to input the URL from the source chain, and then transfer it using CCIP to the destination chain for minting. I have tried to sort this but after sending the transaction on the source chain with the URL, like in the code below, the CCIP transaction is successful but I'm not able to find the NFT on the destination chain. Please, is there anything I am doing wrong in my code below?

 // Build the CCIP Message
function mint(
        uint64 _destinationChainSelector,
        address _receiver,
        address _token,
        uint256 _amount,
        string memory _metadataURL
    ) 
        external
        onlyWhitelistedChain(_destinationChainSelector)
        returns (bytes32 messageId) 
    {
        Client.EVMTokenAmount[]
            memory tokenAmounts = new Client.EVMTokenAmount[](1);
        Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({
            token: _token,
            amount: _amount
        });
        tokenAmounts[0] = tokenAmount;
        
        // Build the CCIP Message
        Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
            receiver: abi.encode(_receiver),
            data: abi.encodeWithSignature("mint(address, string)", msg.sender, _metadataURL),
            tokenAmounts: tokenAmounts,
            extraArgs: "",
            feeToken: address(linkToken)
        });
        
        // CCIP Fees Management
        uint256 fees = router.getFee(_destinationChainSelector, message);

        if (fees > linkToken.balanceOf(address(this)))
            revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees);

        linkToken.approve(address(router), fees);
        
        // Approve Router to spend CCIP-BnM tokens we send
        IERC20(_token).approve(address(router), _amount);
        
        // Send CCIP Message
        messageId = router.ccipSend(_destinationChainSelector, message); 
        
        emit TokensTransferred(
            messageId,
            _destinationChainSelector,
            _receiver,
            _token,
            _amount,
            fees
        ); 
    }
}

This is the mint function on the MyNFT contract in the destination chain.

function mint(address to, string memory TOKEN_URI) public {
    _safeMint(to, tokenId);
    _setTokenURI(tokenId, TOKEN_URI);
    unchecked {
        tokenId++;
    }
}
1

There are 1 answers

2
Andrej On

With the latest CCIP release the strict property of the EVMExtraArgsV1 struct has been removed.

You can solve this issue by refactoring the extraArgs line to either:

extraArgs: Client._argsToBytes(
            Client.EVMExtraArgsV1({gasLimit: 200_000})
        )

Or

extraArgs: "", // this syntax defaults to gasLimit 200_000 and is forward compatible

You should always check the official documentation for the latest updates and best practices, thanks!