0xa9::its
Singleton
ExecutedWithToken
init
register_transaction
get_final_transaction
register_coin
deploy_remote_interchain_token
send_interchain_transfer_call
receive_interchain_transfer
pay_gas_and_send_message
use 0x1::ascii;
use 0x1::string;
use 0x1::type_name;
use 0x2::address;
use 0x2::clock;
use 0x2::coin;
use 0x2::event;
use 0x2::hex;
use 0x2::object;
use 0x2::sui;
use 0x2::transfer;
use 0x2::tx_context;
use 0xa1::channel;
use 0xa1::gateway;
use 0xa1::message_ticket;
use 0xa2::gas_service;
use 0xa5::coin_info;
use 0xa5::coin_management;
use 0xa5::discovery;
use 0xa5::interchain_token_service;
use 0xa5::interchain_transfer_ticket;
use 0xa5::token_id;
use 0xa9::utils;
use 0xaa::discovery;
use 0xaa::transaction;
Singleton
struct Singleton has key
ExecutedWithToken
struct ExecutedWithToken has copy, drop
source_chain: ascii::String
source_address: vector<u8>
data: vector<u8>
amount: u64
init
Setup —–
fun init(ctx: &mut tx_context::TxContext)
fun init(ctx: &mut TxContext) {
let singletonId = object::new(ctx);
let channel = channel::new(ctx);
transfer::share_object(Singleton {
id: singletonId,
channel,
});
}
register_transaction
This needs to be called to register the transaction so that the relayer knows to call this to fulfill calls.
public fun register_transaction(discovery: &mut discovery::RelayerDiscovery, singleton: &its::Singleton, its: &interchain_token_service::InterchainTokenService, clock: &clock::Clock)
public fun register_transaction(
discovery: &mut RelayerDiscovery,
singleton: &Singleton,
its: &InterchainTokenService,
clock: &Clock,
) {
let arguments = vector[
concat(vector[0u8], object::id_address(singleton).to_bytes()),
concat(vector[0u8], object::id_address(its).to_bytes()),
vector[3u8],
concat(vector[0u8], object::id_address(clock).to_bytes()),
];
let transaction = transaction::new_transaction(
false,
vector[
transaction::new_move_call(
transaction::new_function(
address::from_bytes(
hex::decode(
*ascii::as_bytes(
&type_name::get_address(
&type_name::get<Singleton>(),
),
),
),
),
ascii::string(b"its"),
ascii::string(b"get_final_transaction"),
),
arguments,
vector[],
),
],
);
discovery.register_transaction(&singleton.channel, transaction);
}
get_final_transaction
public fun get_final_transaction(singleton: &its::Singleton, its: &interchain_token_service::InterchainTokenService, payload: vector<u8>, clock: &clock::Clock): transaction::Transaction
public fun get_final_transaction(
singleton: &Singleton,
its: &InterchainTokenService,
payload: vector<u8>,
clock: &Clock,
): Transaction {
let arguments = vector[
vector[2u8],
concat(vector[0u8], object::id_address(singleton).to_bytes()),
concat(vector[0u8], object::id_address(its).to_bytes()),
concat(vector[0u8], object::id_address(clock).to_bytes()),
];
// Get the coin type from its
let (token_id, _, _, _) = its_discovery::interchain_transfer_info(
payload,
);
let coin_type = (*its.registered_coin_type(token_id)).into_string();
let transaction = transaction::new_transaction(
true,
vector[
transaction::new_move_call(
transaction::new_function(
address::from_bytes(
hex::decode(
*ascii::as_bytes(
&type_name::get_address(
&type_name::get<Singleton>(),
),
),
),
),
ascii::string(b"its"),
ascii::string(b"receive_interchain_transfer"),
),
arguments,
vector[coin_type],
),
],
);
transaction
}
register_coin
This function needs to be called first to register the coin for either of the other two functions to work.
public fun register_coin<TOKEN>(its: &mut interchain_token_service::InterchainTokenService, coin_metadata: &coin::CoinMetadata<TOKEN>): token_id::TokenId
public fun register_coin<TOKEN>(
its: &mut InterchainTokenService,
coin_metadata: &CoinMetadata<TOKEN>,
): TokenId {
let coin_info = coin_info::from_info<TOKEN>(
coin_metadata.get_name(),
coin_metadata.get_symbol(),
coin_metadata.get_decimals(),
);
let coin_management = coin_management::new_locked();
its.register_coin(
coin_info,
coin_management,
)
}
deploy_remote_interchain_token
public fun deploy_remote_interchain_token<TOKEN>(its: &mut interchain_token_service::InterchainTokenService, gateway: &mut gateway::Gateway, gas_service: &mut gas_service::GasService, destination_chain: ascii::String, token_id: token_id::TokenId, gas: coin::Coin<sui::SUI>, gas_params: vector<u8>, refund_address: address)
public fun deploy_remote_interchain_token<TOKEN>(
its: &mut InterchainTokenService,
gateway: &mut Gateway,
gas_service: &mut GasService,
destination_chain: String,
token_id: TokenId,
gas: Coin<SUI>,
gas_params: vector<u8>,
refund_address: address,
) {
let message_ticket = its.deploy_remote_interchain_token<TOKEN>(
token_id,
destination_chain,
);
pay_gas_and_send_message(
gateway,
gas_service,
gas,
message_ticket,
refund_address,
gas_params,
);
}
send_interchain_transfer_call
This should trigger an interchain trasnfer.
public fun send_interchain_transfer_call<TOKEN>(singleton: &its::Singleton, its: &mut interchain_token_service::InterchainTokenService, gateway: &mut gateway::Gateway, gas_service: &mut gas_service::GasService, token_id: token_id::TokenId, coin: coin::Coin<TOKEN>, destination_chain: ascii::String, destination_address: vector<u8>, metadata: vector<u8>, refund_address: address, gas: coin::Coin<sui::SUI>, gas_params: vector<u8>, clock: &clock::Clock)
public fun send_interchain_transfer_call<TOKEN>(
singleton: &Singleton,
its: &mut InterchainTokenService,
gateway: &mut Gateway,
gas_service: &mut GasService,
token_id: TokenId,
coin: Coin<TOKEN>,
destination_chain: String,
destination_address: vector<u8>,
metadata: vector<u8>,
refund_address: address,
gas: Coin<SUI>,
gas_params: vector<u8>,
clock: &Clock,
) {
let interchain_transfer_ticket = interchain_token_service::prepare_interchain_transfer<TOKEN>(
token_id,
coin,
destination_chain,
destination_address,
metadata,
&singleton.channel,
);
let message_ticket = its.send_interchain_transfer<TOKEN>(
interchain_transfer_ticket,
clock,
);
pay_gas_and_send_message(
gateway,
gas_service,
gas,
message_ticket,
refund_address,
gas_params,
);
}
receive_interchain_transfer
This should receive some coins, give them to the executor, and emit and event with all the relevant info.
public fun receive_interchain_transfer<TOKEN>(approved_message: channel::ApprovedMessage, singleton: &its::Singleton, its: &mut interchain_token_service::InterchainTokenService, clock: &clock::Clock, ctx: &mut tx_context::TxContext)
public fun receive_interchain_transfer<TOKEN>(
approved_message: ApprovedMessage,
singleton: &Singleton,
its: &mut InterchainTokenService,
clock: &Clock,
ctx: &mut TxContext,
) {
let (
source_chain,
source_address,
data,
coin,
) = its.receive_interchain_transfer_with_data<TOKEN>(
approved_message,
&singleton.channel,
clock,
ctx,
);
event::emit(ExecutedWithToken {
source_chain,
source_address,
data,
amount: coin.value(),
});
// give the coin to the caller
transfer::public_transfer(coin, ctx.sender());
}
pay_gas_and_send_message
fun pay_gas_and_send_message(gateway: &gateway::Gateway, gas_service: &mut gas_service::GasService, gas: coin::Coin<sui::SUI>, message_ticket: message_ticket::MessageTicket, refund_address: address, gas_params: vector<u8>)
fun pay_gas_and_send_message(
gateway: &Gateway,
gas_service: &mut GasService,
gas: Coin<SUI>,
message_ticket: MessageTicket,
refund_address: address,
gas_params: vector<u8>,
) {
gas_service.pay_gas(
&message_ticket,
gas,
refund_address,
gas_params,
);
gateway::send_message(gateway, message_ticket);
}