0xa9::its
Singleton
ExecutedWithToken
init
register_transaction
get_final_transaction
register_coin
register_coin_with_cap
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,
)
}
register_coin_with_cap
Registers a coin with the Interchain Token Service (ITS), using the provided TreasuryCap
to manage the coin.
The TreasuryCap
gives the ITS control over minting and burning of this coin.
public fun register_coin_with_cap<TOKEN>(its: &mut interchain_token_service::InterchainTokenService, coin_metadata: &coin::CoinMetadata<TOKEN>, treasury_cap: coin::TreasuryCap<TOKEN>): token_id::TokenId
public fun register_coin_with_cap<TOKEN>(
its: &mut InterchainTokenService,
coin_metadata: &CoinMetadata<TOKEN>,
treasury_cap: TreasuryCap<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_with_cap(treasury_cap);
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);
}