axelar-cgp-sui

Module 0xa1::channel

Channels

Channels allow sending and receiving messages between Sui and other chains. A channel has a unique id and is treated as the destination address by the Axelar protocol. Apps can create a channel and hold on to it for cross-chain messaging.

use 0x1::ascii;
use 0x2::object;
use 0x2::tx_context;
use 0xa1::events;

Resource Channel

The Channel object. Acts as a destination for the messages sent through the bridge. The destination_id is compared against the id of the Channel when the message is consumed

struct Channel has store, key
Fields
id: object::UID
Unique ID of the channel

Struct ApprovedMessage

A HotPotato - this should be received by the application contract and consumed

struct ApprovedMessage
Fields
source_chain: ascii::String
Source chain axelar-registered name
message_id: ascii::String
Unique ID of the message
source_address: ascii::String
Address of the source chain, encoded as a string (e.g. EVM address will be hex string 0x1234...abcd)
destination_id: address
The destination Channel's UID
payload: vector<u8>
Message payload

Constants

If approved message is consumed by an invalid destination id

const EInvalidDestination: vector<u8> = [105, 110, 118, 97, 108, 105, 100, 32, 100, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110];

Function new

Create new Channel object. Anyone can create their own Channel to receive cross-chain messages. In most use cases, a package should create this on init, and hold on to it forever.

public fun new(ctx: &mut tx_context::TxContext): channel::Channel
Implementation
public fun new(ctx: &mut TxContext): Channel {
    let id = object::new(ctx);

    events::channel_created(id.uid_to_address());

    Channel {
        id,
    }
}

Function destroy

Destroy a Channel. Allows apps to destroy the Channel object when it’s no longer needed.

public fun destroy(self: channel::Channel)
Implementation
public fun destroy(self: Channel) {
    let Channel { id } = self;

    events::channel_destroyed(id.uid_to_address());

    id.delete();
}

Function id

public fun id(self: &channel::Channel): object::ID
Implementation
public fun id(self: &Channel): ID {
    object::id(self)
}

Function to_address

public fun to_address(self: &channel::Channel): address
Implementation
public fun to_address(self: &Channel): address {
    object::id_address(self)
}

Function consume_approved_message

Consume an approved message hot potato object intended for this Channel.

public fun consume_approved_message(channel: &channel::Channel, approved_message: channel::ApprovedMessage): (ascii::String, ascii::String, ascii::String, vector<u8>)
Implementation
public fun consume_approved_message(
    channel: &Channel,
    approved_message: ApprovedMessage,
): (String, String, String, vector<u8>) {
    let ApprovedMessage {
        source_chain,
        message_id,
        source_address,
        destination_id,
        payload,
    } = approved_message;

    // Check if the message is sent to the correct destination.
    assert!(destination_id == object::id_address(channel), EInvalidDestination);

    (source_chain, message_id, source_address, payload)
}

Function create_approved_message

Create a new ApprovedMessage object to be sent to another chain. Is called by the gateway when a message is “picked up” by the relayer.

public(friend) fun create_approved_message(source_chain: ascii::String, message_id: ascii::String, source_address: ascii::String, destination_id: address, payload: vector<u8>): channel::ApprovedMessage
Implementation
public(package) fun create_approved_message(
    source_chain: String,
    message_id: String,
    source_address: String,
    destination_id: address,
    payload: vector<u8>,
): ApprovedMessage {
    ApprovedMessage {
        source_chain,
        message_id,
        source_address,
        destination_id,
        payload,
    }
}