For this part of the workshop we will be minting on a new destination. In the Recorded Workshop, the destination Chain was Polygon Mumbai, However, Mumbai has been deprecated so we will be changing it
We will demonstrate how you can send messages & mint tokens across multiple chains using Chainlink CCIP
We will demonstrate how you can send messages & mint tokens across multiple chains using Chainlink CCIP
We will be using Base Sepolia instead, since Polygon Mumbai was deprecated in April 2024.
Follow this link to switch your Metamask wallet to the Base Sepolia network - Make sure the Chain ID is 84532
Use the Faucet to receive some LINK and ETH on the Base Sepolia Network
Make sure you add the LINK token to your wallet by importing it as per the above links. You can either do that by copying the Link token address and manually importing it, or by clicking the button provided.
Now that we have our important prerequisites taken care of, lets dive into the code. Make a new file in Remix, CrossSourceMinterBaseSepolia.sol and copy the following in there.
// SPDX-License-Identifier: MITpragmasolidity 0.8.19;// Deploy this contract on Base Sepoliaimport {IRouterClient} from"@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol";import {Client} from"@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol";import {LinkTokenInterface} from"@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";/** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */contract CrossSourceMinterBaseSepolia {// Custom errors to provide more descriptive revert messages. error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees); // Used to make sure contract has enough balance to cover the fees.
errorNothingToWithdraw(); // Used when trying to withdraw but there's nothing to withdraw. IRouterClient public router; LinkTokenInterface public linkToken;uint64public destinationChainSelector;addresspublic owner;addresspublic destinationMinter;eventMessageSent(bytes32 messageId);constructor(address destMinterAddress) { owner = msg.sender;// https://docs.chain.link/ccip/supported-networks/testnet// from Base Sepoliaaddress routerAddressBaseSepolia =0xD3b06cEbF099CE7DA4AcCf578aaebFDBd6e88a93; router =IRouterClient(routerAddressBaseSepolia); linkToken =LinkTokenInterface(0xE4aB69C077896252FAFBD49EFD26B5D171A32410); linkToken.approve(routerAddressBaseSepolia, type(uint256).max);// to Sepolia destinationChainSelector =16015286601757825753; destinationMinter = destMinterAddress; }functionmintOnEthSepolia() external {// Mint from Base Sepolia network = chain[2] Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ receiver: abi.encode(destinationMinter), data: abi.encodeWithSignature("mintFrom(address,uint256)", msg.sender,2), tokenAmounts:new Client.EVMTokenAmount[](0), extraArgs: Client._argsToBytes( Client.EVMExtraArgsV1({gasLimit:980_000}) ), feeToken:address(linkToken) }); // Get the fee required to send the messageuint256 fees = router.getFee(destinationChainSelector, message);if (fees > linkToken.balanceOf(address(this)))revertNotEnoughBalance(linkToken.balanceOf(address(this)), fees);bytes32 messageId;// Send the message through the router and store the returned message ID messageId = router.ccipSend(destinationChainSelector, message);emitMessageSent(messageId); }modifieronlyOwner() {require(msg.sender == owner); _; }functionlinkBalance (address account) publicviewreturns (uint256) {return linkToken.balanceOf(account); }functionwithdrawLINK(address beneficiary ) publiconlyOwner {uint256 amount = linkToken.balanceOf(address(this));if (amount ==0) revertNothingToWithdraw(); linkToken.transfer(beneficiary, amount); }}
Copy this code into your new CrossSourceMinterBase.sol File
Go to the Deployment tab and include your CrossDestinationMinter.sol's address as the parameter (this is the same contract we deployed on Ethereum Sepolia)
Now send the newly created CrossSourceMinterBaseSepolia contract 5 LINK so it can pay for operations.
Once LINK is in the contract you should confirm that it is there by clicking the linkBalance button and pass the CrossSourceMinterBaseSepolia address as the input parameter.