0.3.10 • Published 2 years ago

@cryptolink/contracts v0.3.10

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

CryptoLink Cross-Chain Messaging NPM Package Documentation

Table of Contents

Introduction

CryptoLink's Cross-Chain Messaging npm package (@cryptolink/contracts) streamlines the integration of cross-chain communication in blockchain applications.

Benefits of Using the NPM Package

  • Simplified cross-chain communication setup.
  • Compatibility with various EVM-compatible chains.
  • Direct integration with CryptoLink's infrastructure.

Installation and Setup

Install the package from NPM:

npm install @cryptolink/contracts

Note: Alternatively, the package can be installed locally by fetching it from the GitHub repository.

Implementing MessageV3Client

  • Inheritance: Extend your contract from MessageClient.
  • Message Sending: Use _sendMessage and _sendMessageExpress.
  • Message Processing: Implement messageProcess for incoming message handling.

See Examples for detailed use cases.

Contract Function Details

  • configureClient: Sets chain-specific configurations and enables/disables chains.
  • setMaxgas: Defines maximum gas refund allowed per transaction.
  • setMaxfee: Sets a cap on transaction fees that the system can charge per message.
  • setExsig: Assigns external signatures for security enhancement.

Function examples are provided in the relevant sections.

Example Implementation and Explanation

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@cryptolink/contracts/message/MessageClient.sol";

contract MyCrossChainContract is MessageClient {
    // Constructor to set up the MessageV3 Client
    constructor(address messageV3Address) {
        MESSAGEv3 = IMessageV3(messageV3Address);
    }

    // Function to send a message to another chain
    function sendMessageToAnotherChain(uint destinationChainId, bytes memory data) public {
        // Sending a message to the specified chain
        uint txId = _sendMessage(destinationChainId, data);
        // Additional logic after sending the message (if needed)
    }

    // Function to send a message using express mode
    function sendExpressMessageToAnotherChain(uint destinationChainId, bytes memory data) public {
        // Sending a message using express mode
        uint txId = _sendMessageExpress(destinationChainId, data);
        // Additional logic after sending the message (if needed)
    }

    // Overriding the messageProcess function to handle incoming messages
    function messageProcess(
        uint _txId, uint _sourceChainId, address _sender, address _reference, 
        uint _amount, bytes calldata _data
    ) external override onlySelf(_sender, _sourceChainId) {
        // Decode the incoming message and process it
        // Example: (address from, uint256 value) = abi.decode(_data, (address, uint256));
        // Process the message as required
    }

    // Additional functions and logic as required for your contract
    // ...
}

Notes on the Example Code

  • Initialization: The contract is initialized with the address of the Message system, which is crucial for enabling cross-chain messaging.
  • Sending Messages: The sendMessageToAnotherChain and sendMessageExpress functions illustrate how to send standard and express messages to other chains.
  • Processing Incoming Messages: The messageProcess function is overridden to handle messages received from other chains. This function should be customized based on how you want to process incoming messages.
  • Security: The onlySelf modifier ensures that only messages sent through the established Message system and configured remote contracts are processed.
  • Customization: This example provides a basic structure. You should customize the logic within these functions to fit your specific application requirements.

Breakdown of Key Components

  1. Contract Declaration and Inheritance

    • pragma solidity ^0.8.9;: Specifies the Solidity compiler version for compatibility.
    • import "@cryptolink/contracts/message/MessageClient.sol";: Imports the MessageClient abstract contract.
    • contract MyCrossChainContract is MessageClient: Declares a new contract MyCrossChainContract that inherits the functionalities of MessageClient.
  2. Function: messageProcess

    • Purpose: Processes incoming messages from other chains.
    • Declaration:
      function messageProcess(uint _txId, uint _sourceChainId, address _sender, address _reference, uint _amount, bytes calldata _data) external virtual onlySelf(_sender, _sourceChainId) {}
    • Implementation: Override this function in your contract to define how incoming messages should be processed.
  3. Function: _sendMessage

    • Purpose: Sends a message to a specified chain.
    • Declaration:
      function _sendMessage(uint _destinationChainId, bytes memory _data) internal returns (uint _txId) {}
    • Implementation: Used internally to send messages to other chains. Invokes sendMessage of the MESSAGEv3 interface.
  4. Function: _sendMessageExpress

    • Purpose: Sends a message to a specified chain using express mode.
    • Declaration:
      function _sendMessageExpress(uint _destinationChainId, bytes memory _data) internal returns (uint _txId) {}
    • Implementation: Similar to _sendMessage but sends the message in express mode.

Using the MessageClient ABI

You can import the ABI for the MessageClient contract directly from the package:

// Using CommonJS
const { MessageClientABI } = require('@cryptolink/contracts/abis');

// Using ES6 imports
import { MessageClientABI } from '@cryptolink/contracts/abis';

You can then load contracts using this ABI:

const myContract = new ethers.Contract(contractAddress, MessageClientABI, signer);

Using the MessageClient Configuration

You can import common addresses and configuration for the MessageClient contract directly from the package:

// Using CommonJS
const chainsConfig = require('@cryptolink/contracts/config/chains');

// Using ES6 imports
import chainsConfig from '@cryptolink/contracts/config/chains';

You can then reference values from chains by using the chainId as an index:

// Get the message contract address of the current network
const messageAddress = chainsConfig[hre.network.config.chainId].message; 

After Deployment Configuration Script

This script is an example to be ran after all of the corresponding Client contracts have been deployed and addresses collected. This script is used to enable all of the desired chains and configure each of the contracts to accept messages from each other utilizing the configureClient() function in the package.

const { ethers } = require('ethers');
const chainsConfig = require('@cryptolink/contracts/config/chains');
const { MessageClientABI } = require('@cryptolink/contracts/message/abi');

async function configureContract() {
    // Configuration Parameters
    const rpcUrl = 'https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY'; // Example Ethereum RPC URL
    const privateKey = '0xYOUR_PRIVATE_KEY'; // Example private key
    const contractAddress = '0xabcd...1234'; // Example deployed contract address on Ethereum

    // Initialize ethers with provider and signer
    const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
    const signer = new ethers.Wallet(privateKey, provider);

    // Instantiate the contract
    const myContract = new ethers.Contract(contractAddress, MessageClientABI, signer);

    try {
        const chains = [5, 11155111, 17000]; // Desired chain IDs
        const endpoints = ['0x000000','0x000000','0x000000']; // YOUR deployed instances of ATWTest on each chain
        const confirmations = [12, 6, 6]; // Desired confirmation counts for each chain

        // Configure the client with MessageV3 address and chain data
        const tx = await myContract.configureClient(
            chainsConfig[hre.network.config.chainId].message, // Use the message contract address of the current network
            chains, 
            endpoints, 
            confirmations
        );

        console.log('Transaction sent:', tx.hash);
        await tx.wait();
        console.log('Chains configured successfully.');
    } catch (error) {
        console.error('An error occurred during configuration:', error);
    }
}

// Execute the configuration
configureContract();

Fee Management

Fees and Gas

The fee management in cross-chain messaging involves two main types of fees: gas fees on the destination chain and source fees on the origin chain. Gas fees are paid in the wrapped native gas token of the respective blockchain, such as WETH on Ethereum, WMATIC on Polygon, and WBNB on Binance Smart Chain. Source fees are paid in FEE_TOKEN. The NPM package facilitates automatic approval for these tokens, ensuring that fees are deducted during transaction processing. Developers are responsible for ensuring their contracts have sufficient funds in both the wrapped native gas token and FEE_TOKEN. They also have the option to set limits on these fees using setMaxgas and setMaxFee functions for added protection against unexpected fee increases.

Handling Gas Fees on Destination Chain

Gas fees are paid in the wrapped native gas token of the respective blockchain (e.g., WETH on Ethereum, WMATIC on Polygon, WBNB on Binance Smart Chain). The recieving contract (yours) needs to have available WETH in the contract to pay for the transaction costs. If the funds are not available, or not approved for the message system to take, the transaction will not be processed. It is up to the contract developers to determine how the WETH is charged, either by the protocol or by taking from the users directly.

Managing Source Fees on Origin Chain

Source chain fees are paid in FEE_TOKEN. If the calling contract does not have the available FEE_TOKEN the transaction will revert and no messages will be sent. It is up to the contract developers to determine where the FEE_TOKEN funds are obtained. The calling contract is required to have available funds at time of calling the contract, so if it is taken from the user it must be done so before the message is sent.

Automatic Fee Approval

The NPM package automatically approves the wrapped native gas token (like WETH, WMATIC) and FEE_TOKEN, enabling the Message system to automatically deduct fees during transaction processing.

Ensuring Funds for Fees

Developers must ensure their contracts have sufficient funds in the wrapped native gas token and FEE_TOKEN for fees. This can be achieved either by depositing funds or designing the contract to collect these from users.

Fee Limits for Protection

Functions setMaxgas and setMaxFee allow developers to set limits on gas and message fees, offering protection against high or unexpected fees.

Recovering Fee and Gas Tokens

The recoverToken allows the contract owner to recover funds sent to the contract by mistake, either ERC20 or ETH. If you do not wish to allow recovery, or you wish to limit the recovery of tokens to specific tokens, please override this function in your contract.

Supported Chains

Mainnets

Chain NameChain IDContract Address
Alveychain Mainnet37970x65EEc58ef38882422E887B82f7085e9a9C35dCA1
Arbitrum Mainnet421610x65EEc58ef38882422E887B82f7085e9a9C35dCA1
Aurora Mainnet13131615550xf0861412E46E34DaF7A1fe3fe805e7f713cA3bD9
Avalanche Mainnet431140x72E052Fa7f0788e668965d37B6c38C88703B7859
Base Mainnet84530xe3b3274bb685F37C7f17a604039c77a6A16Cfc2a
Binance Mainnet560x7b67dF6728E294db2eb173ac7c738a4627Ae5e11
Celo Mainnet422200xe3b3274bb685F37C7f17a604039c77a6A16Cfc2a
Cronos Mainnet250x2224ac62d65453a2317b995fc084e966e4bac2d5
Ethereum Mainnet10x7b67dF6728E294db2eb173ac7c738a4627Ae5e11
Fantom Mainnet2500x72E052Fa7f0788e668965d37B6c38C88703B7859
Gauss Mainnet17770xfDdE8946A0A1755b3a74afE7b3383dEe4fb5712f
Gnosis Mainnet1000x75c0223A8f9f8f3baB3FbC6d151381C3C576Ba36
Harmony Mainnet16666000000x440AA59AC28460a43537a2eA892d96Acd8eaBdb0
Kava Mainnet22220x9E0f7B09576D1F0cBfF1f834A8e5bcc3Db1EF804
Linea Mainnet591440x6C5AD5e9763Ee118f6c6359e00EeF6ECfA84395b
Mainnetz Mainnet20160x1274E183AA921972531414Df700E673dE1Be878D
Metis Mainnet10880xA10953dEFac127d1b7A645f81045aB5127893124
Oasis Emerald Mainnet422620xe3b3274bb685F37C7f17a604039c77a6A16Cfc2a
Oasis Sapphire Mainnet232940x5E9DBAC1d92b04E5Bd8Bd42845B315568b969Da0
opBNB Mainnet2040x1274E183AA921972531414Df700E673dE1Be878D
Polygon Mainnet1370x1C5800eb5fECB7760D7F1978ad744feA652a7b27
PolygonZK Mainnet1101
Pulse Mainnet3690xba01F2bA548e69bA26Fd06a3bdf1A7857eeAC435
Rollux Mainnet5700xf0861412E46E34DaF7A1fe3fe805e7f713cA3bD9
Scroll Mainnet534352
XDC Mainnet50

Testnets

Chain NameChain IDContract Address
Arbitrum Testnet (Sepolia)4216140x0D7e59B0390e47E6C3a29cCdF68e43f3e50e2119
Aurora Testnet13131615550x52e1CFE18BD55bb8d885d463DC26D9C365cd316B
Autonity Testnet650100010xA95c0BC77Ab8a8EfA3dF00366FFAe5CB1A2cba15
Avalanche Testnet431130x8f92F60ffFB05d8c64E755e54A216090D8D6Eaf9
Base Testnet (Sepolia)845320xE700Ee5d8B7dEc62987849356821731591c048cF
Binance Testnet970x8eF8870CD5583891bDDcf2555e7833bD087392a3
Blast Testnet (Sepolia)1685877730xA95c0BC77Ab8a8EfA3dF00366FFAe5CB1A2cba15
Boba Testnet28880x1Ec7Dfbc9e310768A17145f03f3451f562cEc773
Canto Testnet77010x09FC1B8e1651A0D35258Ab919035d3087245F8f3
Celo Testnet447870xc959284fae7Cc3F41367dA2Df595b7267597094C
Cronos Testnet3380x8f92F60ffFB05d8c64E755e54A216090D8D6Eaf9
CronosZK Testnet2820xCf421b3497a28b4215F09e5bAf862C3a2532d681
Ethereum Goerli50xae65E2211c4119cf92ee85D1a8c4ec20AdaE8aFE
Ethereum Holesky170000x668de98389d5d6C9064E40Cfda2FC6471EDDE7ff
Ethereum Sepolia111551110xF2AA17F92d4D9Be1c0b0D2A3235A06143A2D729f
Fantom Testnet40020x48964a49B5826DB6Cb8d8ed0dAf93eEeD734b923
Forest Testnet3770x3B5b764229b2EdE0162220aF51ab6bf7f8527a4F
Frame Testnet688401420xCb69924aDf996315aDcd9051ccE2B572dD9450a9
Gauss Testnet14520xcbC2d50FA324c187adcf4a186fCb7EcC092E0758
Gelato OP Celestia Testnet1234201110xAede7a77D49Eb88Cb129896d69f0E66ee51D44AC
Gelato OP Testnet420690xAede7a77D49Eb88Cb129896d69f0E66ee51D44AC
Gelato ZKatana Testnet12611200xAede7a77D49Eb88Cb129896d69f0E66ee51D44AC
Gnosis Testnet102000x88776c0FbaCA594938C6B87a42a69D530A8CCDF3
Harmony Testnet16667000000x9cAa65b69Ad8118C3d1454393F5b96292FE3C0aB
Horizen Testnet16630xA95c0BC77Ab8a8EfA3dF00366FFAe5CB1A2cba15
Immutable Testnet134730xC7E87B6614DAb7a4B3Feaa9e56a2cA29A84AD0a8
Katla Testnet1670080xA95c0BC77Ab8a8EfA3dF00366FFAe5CB1A2cba15
Kava Testnet22210xd577fcBee5734c2da5e0063fF1df38845DaA7117
Klaytn Testnet10010xdCa897f920Df8015169838c428479D5e3d5Bf526
Kyoto Testnet19980xdCa897f920Df8015169838c428479D5e3d5Bf526
Linea Testnet591400x0eefCF172F7e5C04A8d565f4e955968221fDb18f
Mainnetz Testnet97680x714c9202B3B5AF0C0Ad844c2a71803cebBFD3AF5
Mantle Testnet50010x02894D48c53Ad4AF56ab9624A07153C4fc379D9C
Metis Testnet5990x8E872249C1D7c533bCDC04f5ac124eCa603E0b6D
Nexis Testnet2370
Oasis Emerald Testnet422610x9Ca377D441B01A44fEab8D75B992ab2e4f710BA9
Oasis Sapphire Testnet232950x9c90eC23162C818A79B46C79Bb6EBC07C6733919
OKEx Testnet650x9744D38d26eF45C31c8D20783671506FebeDBAC4
Onus Testnet19450xF8d80d6E52b5B8484a7CD27a5C0F3D35695c57dF
opBNB Testnet56110x7bB78097d7e672D65cD6596Ee9b4097CE16AC391
Optimism Testnet111554200xe511183765E1F325702EF8F3d92046e9d6DF6742
Polygon Testnet800010x524d9E4cB344A130696B29c182aA5a4A458379B6
Polygon zkEVM Testnet14420xe72599F2F5C8aA96E578E48A09Bc6C1123fA5783
Pulse Testnet9430x91e26475016B923527B5Ef15789A9768EBA979e6
Redstone Testnet170010x1Ec7Dfbc9e310768A17145f03f3451f562cEc773
Rollux Testnet570000x7bB78097d7e672D65cD6596Ee9b4097CE16AC391
Scroll Testnet (Sepolia)5343510x8Dcb34c02365116565A3d68b97e4ae98F983B9D0
Sonic Testnet641650xeFaDc14c2DD95D0E6969d0B25EA6e4F830150493
Stratos Testnet20470x4a7B33299a21c518d77eb3fF00fd1DC39C452Cba
Telos Testnet410xF8d80d6E52b5B8484a7CD27a5C0F3D35695c57dF
X1 Testnet1950x8f554B1b239a57C840d5902D1d901dAFF04F22C2
XDC Testnet510x00CE686319d401E55c2E7784192EB3A2273Aa9Dc
ZetaChain Testnet70010x714c9202B3B5AF0C0Ad844c2a71803cebBFD3AF5
zkSync Testnet2800xCf421b3497a28b4215F09e5bAf862C3a2532d681

Example Use Cases

  1. Cross-Chain Non-Fungible Tokens (NFTs): CryptoLink enables the creation and management of NFTs that exist across multiple blockchains. This opens up new avenues for artists and collectors, increasing market reach and creative possibilities.

  2. Rebroadcasting Oracle Data: The platform allows for oracle data to be broadcasted across many EVM chains, with the possibility for the oracle owner to run their own validation layer. This is crucial for maintaining data consistency and reliability across different blockchains.

  3. Multi-Chain Initial Coin Offerings (ICOs): With CryptoLink, projects can conduct ICOs across various blockchains, allowing them to tap into diverse communities and maximize potential contributions.

  4. Cross-Chain Lending Platforms: The technology can be used to build platforms where users can lend and borrow assets across different blockchains, enhancing the efficiency of capital utilization in the decentralized finance (DeFi) space.

  5. Arbitrage Bots: By identifying and capitalizing on arbitrage opportunities across multiple chains, traders and investors can maximize profits by leveraging price discrepancies.

  6. Unified Metaverses: CryptoLink's technology can be used to build interconnected virtual worlds that span multiple blockchains, leading to more immersive and engaging user experiences.

  7. Social Media Notifications: Innovative applications can be developed where cross-chain events trigger social media notifications, enhancing user engagement and interaction within the cross-chain ecosystem.

Full Contract Documentation

Functions

1. messageProcess

  • Purpose: Processes incoming messages from other chains.
  • Visibility: External
  • Modifiers: onlySelf
  • Parameters:
    • _txId (uint): Transaction ID.
    • _sourceChainId (uint): Source chain ID.
    • _sender (address): Address of the sender's MessageClient contract on the source chain.
    • _reference (address): Optional source reference address.
    • _amount (uint): Not used for messages, always 0.
    • _data (bytes): Encoded message from the source chain.
  • Returns: None

2. _sendMessage

  • Purpose: Sends a message to a specified chain.
  • Visibility: Internal
  • Parameters:
    • _destinationChainId (uint): Destination chain ID.
    • _data (bytes): Arbitrary data package to send.
  • Returns:
    • _txId (uint): Transaction ID of the sent message.

3. _sendMessageExpress

  • Purpose: Sends a message to a specified chain using express mode.
  • Visibility: Internal
  • Parameters:
    • _destinationChainId (uint): Destination chain ID.
    • _data (bytes): Arbitrary data package to send.
  • Returns:
    • _txId (uint): Transaction ID of the sent message.

4. configureClient

  • Purpose: Configures the client with MessageV3 address and chain data.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _messageV3 (address): MessageV3 address.
    • _chains (uint[]): List of chain IDs to accept as valid destinations.
    • _endpoints (address[]): List of corresponding MessageClient addresses on each chain.
    • _confirmations (uint16[]): Confirmations required on each chain before processing.
  • Returns: None

5. setExsig

  • Purpose: Assigns an external signature for enhanced security.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _signer (address): Address of the signer.
  • Returns: None

6. setMaxgas

  • Purpose: Limits the gas usage for transactions.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _maxGas (uint): Maximum gas amount.
  • Returns: None

7. setMaxfee

  • Purpose: Caps the fee amount per transaction.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _maxFee (uint): Maximum fee amount.
  • Returns: None

8. recoverFeeToken

  • Purpose: Recovers Fee Tokens from the contract.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _amount (uint): Amount of tokens to recover.
  • Returns: None

9. recoverGasToken

  • Purpose: Recovers Gas Tokens (WETH) from the contract.
  • Visibility: External
  • Modifiers: onlyMessageOwner
  • Parameters:
    • _amount (uint): Amount of tokens to recover.
  • Returns: None

Modifiers

1. onlySelf

  • Purpose: Ensures that the function is called only by the authorized MessageClient contract from the source chain. This modifier will pass if the message originated from any deployment of this contract on any chain.

2. onlyActiveChain

  • Purpose: Ensures that the destination chain is active before sending a message.

3. onlyMessageOwner

  • Purpose: Restricts function access to the set owner.

Functions based off OpenZeppelin's Ownable

  1. renounceMessageOwnership()

    • Purpose: Leaves the contract without an owner, making it impossible to call onlyMessageOwner functions.
    • Visibility: Public
    • Important Note: Use with caution as it removes any functionality only available to the owner.
  2. transferMessageOwnership(newOwner)

    • Purpose: Transfers ownership of the contract to a new account (newOwner).
    • Visibility: Public
    • Parameters:
      • newOwner (address): Address of the new owner.

Event

  1. MessageOwnershipTransferred(previousOwner, newOwner)
    • Purpose: Emitted when ownership of the contract is transferred.
    • Parameters:
      • previousOwner (address): Address of the previous owner.
      • newOwner (address): Address of the new owner.
0.3.10

2 years ago

0.3.9

2 years ago

0.3.8

2 years ago

0.3.7

2 years ago

0.3.6

2 years ago

0.3.5

2 years ago

0.3.4

2 years ago

0.3.3

2 years ago

0.3.1

2 years ago

0.3.0

2 years ago

0.2.8

2 years ago

0.2.7

2 years ago

0.2.6

2 years ago

0.2.5

2 years ago

0.2.4

2 years ago

0.2.3

2 years ago