axelar-cgp-sui

Module 0xa5::discovery

use 0x1::ascii;
use 0x1::type_name;
use 0x1::vector;
use 0x2::address;
use 0x2::object;
use 0xa0::abi;
use 0xa2::discovery;
use 0xa2::transaction;
use 0xa5::its;
use 0xa5::its_v0;
use 0xa5::token_id;

Constants

const EInvalidMessageType: u64 = 0;

const MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN: u256 = 1;

const MESSAGE_TYPE_INTERCHAIN_TRANSFER: u256 = 0;

const MESSAGE_TYPE_RECEIVE_FROM_HUB: u256 = 4;

const EUnsupportedMessageType: u64 = 0;

Function interchain_transfer_info

public fun interchain_transfer_info(payload: vector<u8>): (token_id::TokenId, address, u64, vector<u8>)
Implementation
public fun interchain_transfer_info(
    payload: vector<u8>,
): (TokenId, address, u64, vector<u8>) {
    let mut reader = abi::new_reader(payload);
    assert!(
        reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER,
        EInvalidMessageType,
    );

    let token_id = token_id::from_u256(reader.read_u256());
    reader.skip_slot(); // skip source_address
    let destination = address::from_bytes(reader.read_bytes());
    let amount = (reader.read_u256() as u64);
    let data = reader.read_bytes();

    (token_id, destination, amount, data)
}

Function register_transaction

public fun register_transaction(its: &mut its::ITS, discovery: &mut discovery::RelayerDiscovery)
Implementation
public fun register_transaction(
    its: &mut ITS,
    discovery: &mut RelayerDiscovery,
) {
    let mut arg = vector[0];
    arg.append(object::id(its).to_bytes());

    let arguments = vector[arg, vector[3]];

    let function = transaction::new_function(
        package_id<ITS>(),
        ascii::string(b"discovery"),
        ascii::string(b"call_info"),
    );

    let move_call = transaction::new_move_call(
        function,
        arguments,
        vector[],
    );

    its.register_transaction(
        discovery,
        transaction::new_transaction(
            false,
            vector[move_call],
        ),
    );
}

Function call_info

public fun call_info(its: &its::ITS, payload: vector<u8>): transaction::Transaction
Implementation
public fun call_info(its: &ITS, mut payload: vector<u8>): Transaction {
    let mut reader = abi::new_reader(payload);
    let mut message_type = reader.read_u256();

    if (message_type == MESSAGE_TYPE_RECEIVE_FROM_HUB) {
        reader.skip_slot();
        payload = reader.read_bytes();
        reader = abi::new_reader(payload);
        message_type = reader.read_u256();
    };

    if (message_type == MESSAGE_TYPE_INTERCHAIN_TRANSFER) {
        interchain_transfer_tx(its, &mut reader)
    } else {
        assert!(
            message_type == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN,
            EUnsupportedMessageType,
        );
        deploy_interchain_token_tx(its, &mut reader)
    }
}

Function interchain_transfer_tx

fun interchain_transfer_tx(its: &its::ITS, reader: &mut abi::AbiReader): transaction::Transaction
Implementation
fun interchain_transfer_tx(its: &ITS, reader: &mut AbiReader): Transaction {
    let token_id = token_id::from_u256(reader.read_u256());
    reader.skip_slot(); // skip source_address
    let destination_address = address::from_bytes(reader.read_bytes());
    reader.skip_slot(); // skip amount
    let data = reader.read_bytes();
    let value = its.package_value();

    if (data.is_empty()) {
        let mut arg = vector[0];
        arg.append(object::id_address(its).to_bytes());

        let type_name = value.registered_coin_type(token_id);

        let arguments = vector[arg, vector[2], vector[0, 6]];

        transaction::new_transaction(
            true,
            vector[
                transaction::new_move_call(
                    transaction::new_function(
                        package_id<ITS>(),
                        ascii::string(b"its"),
                        ascii::string(b"receive_interchain_transfer"),
                    ),
                    arguments,
                    vector[type_name::into_string(*type_name)],
                ),
            ],
        )
    } else {
        let mut discovery_arg = vector[0];
        discovery_arg.append(value
            .relayer_discovery_id()
            .id_to_address()
            .to_bytes());

        let mut channel_id_arg = vector[1];
        channel_id_arg.append(destination_address.to_bytes());

        transaction::new_transaction(
            false,
            vector[
                transaction::new_move_call(
                    transaction::new_function(
                        package_id<RelayerDiscovery>(),
                        ascii::string(b"discovery"),
                        ascii::string(b"get_transaction"),
                    ),
                    vector[discovery_arg, channel_id_arg ],
                    vector[],
                ),
            ],
        )
    }
}

Function deploy_interchain_token_tx

fun deploy_interchain_token_tx(its: &its::ITS, reader: &mut abi::AbiReader): transaction::Transaction
Implementation
fun deploy_interchain_token_tx(its: &ITS, reader: &mut AbiReader): Transaction {
    let mut arg = vector[0];
    arg.append(object::id_address(its).to_bytes());

    let arguments = vector[arg, vector[2]];

    reader.skip_slot(); // skip token_id
    reader.skip_slot(); // skip _name
    let symbol = ascii::string(reader.read_bytes());
    let decimals = (reader.read_u256() as u8);
    reader.skip_slot(); // skip distributor

    let value = its.package_value();
    let type_name = value.unregistered_coin_type(&symbol, decimals);

    let move_call = transaction::new_move_call(
        transaction::new_function(
            package_id<ITS>(),
            ascii::string(b"its"),
            ascii::string(b"receive_deploy_interchain_token"),
        ),
        arguments,
        vector[type_name::into_string(*type_name)],
    );

    transaction::new_transaction(
        true,
        vector[move_call],
    )
}