Created
May 5, 2024 08:07
-
-
Save QingyangKong/7b506976af64485c7bc9647bef11d837 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.8.19; | |
// Deploy this contract on Fuji | |
// Use address of CrossChainMinter.sol deployed on Sepolia in contructor | |
// Call the function mintOnSepolia() to mint a nft in sepolia | |
import {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 CrossSourceMinter { | |
// 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. | |
error NothingToWithdraw(); // Used when trying to withdraw but there's nothing to withdraw. | |
IRouterClient public router; | |
LinkTokenInterface public linkToken; | |
uint64 public destinationChainSelector; | |
address public owner; | |
address public destinationMinter; | |
event MessageSent(bytes32 messageId); | |
constructor(address destMinterAddress) { | |
owner = msg.sender; | |
// https://docs.chain.link/ccip/supported-networks/testnet | |
// from Fuji | |
address routerAddressFuji = 0xF694E193200268f9a4868e4Aa017A0118C9a8177; | |
router = IRouterClient(routerAddressFuji); | |
linkToken = LinkTokenInterface(0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846); | |
linkToken.approve(routerAddressFuji, type(uint256).max); | |
// to Sepolia | |
destinationChainSelector = 16015286601757825753; | |
destinationMinter = destMinterAddress; | |
} | |
function mintOnSepolia() external { | |
// Mint from Fuji network = chain[1] | |
Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ | |
receiver: abi.encode(destinationMinter), | |
data: abi.encodeWithSignature("mintFrom(address,uint256)", msg.sender, 1), | |
tokenAmounts: new Client.EVMTokenAmount[](0), | |
extraArgs: Client._argsToBytes( | |
Client.EVMExtraArgsV1({gasLimit: 980_000}) | |
), | |
feeToken: address(linkToken) | |
}); | |
// Get the fee required to send the message | |
uint256 fees = router.getFee(destinationChainSelector, message); | |
if (fees > linkToken.balanceOf(address(this))) | |
revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees); | |
bytes32 messageId; | |
// Send the message through the router and store the returned message ID | |
messageId = router.ccipSend(destinationChainSelector, message); | |
emit MessageSent(messageId); | |
} | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
function linkBalance (address account) public view returns (uint256) { | |
return linkToken.balanceOf(account); | |
} | |
function withdrawLINK( | |
address beneficiary | |
) public onlyOwner { | |
uint256 amount = linkToken.balanceOf(address(this)); | |
if (amount == 0) revert NothingToWithdraw(); | |
linkToken.transfer(beneficiary, amount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment