0xa5::interchain_token_service_v0
InterchainTokenService_v0
new
unregistered_coin_type
registered_coin_type
channel_address
set_relayer_discovery_id
relayer_discovery_id
set_trusted_address
remove_trusted_address
set_trusted_addresses
remove_trusted_addresses
channel
version_control
register_coin
deploy_remote_interchain_token
send_interchain_transfer
receive_interchain_transfer
receive_interchain_transfer_with_data
receive_deploy_interchain_token
give_unregistered_coin
mint_as_distributor
mint_to_as_distributor
burn_as_distributor
set_flow_limit_as_token_operator
set_flow_limit
allow_function
disallow_function
coin_data
coin_info
is_trusted_address
coin_management_mut
add_unregistered_coin
remove_unregistered_coin
trusted_address
add_unregistered_coin_type
remove_unregistered_coin_type
add_registered_coin_type
add_registered_coin
prepare_message
decode_approved_message
read_amount
use 0x1::ascii;
use 0x1::option;
use 0x1::string;
use 0x1::type_name;
use 0x1::vector;
use 0x2::address;
use 0x2::bag;
use 0x2::balance;
use 0x2::clock;
use 0x2::coin;
use 0x2::object;
use 0x2::table;
use 0x2::transfer;
use 0x2::tx_context;
use 0x2::url;
use 0xa0::abi;
use 0xa1::channel;
use 0xa1::gateway;
use 0xa1::message_ticket;
use 0xa5::address_tracker;
use 0xa5::coin_data;
use 0xa5::coin_info;
use 0xa5::coin_management;
use 0xa5::events;
use 0xa5::interchain_transfer_ticket;
use 0xa5::token_id;
use 0xa5::trusted_addresses;
use 0xa5::unregistered_coin_data;
use 0xa5::utils;
use 0xaa::discovery;
use 0xb0::version_control;
InterchainTokenService_v0
struct InterchainTokenService_v0 has store
channel: channel::Channel
address_tracker: address_tracker::InterchainAddressTracker
unregistered_coin_types: table::Table<token_id::UnregisteredTokenId, type_name::TypeName>
unregistered_coins: bag::Bag
registered_coin_types: table::Table<token_id::TokenId, type_name::TypeName>
registered_coins: bag::Bag
relayer_discovery_id: object::ID
version_control: version_control::VersionControl
#[error]
const EOverflow: vector<u8> = b"cannot receive more than 2^64-1 coins";
#[error]
const EInterchainTransferHasData: vector<u8> = b"interchain transfer with data trying to be processed as an interchain transfer";
#[error]
const EInterchainTransferHasNoData: vector<u8> = b"interchain transfer trying to be proccessed as an interchain transfer";
#[error]
const EInvalidMessageType: vector<u8> = b"the message type received is not supported";
#[error]
const EModuleNameDoesNotMatchSymbol: vector<u8> = b"the module name does not match the symbol";
#[error]
const ENewerTicket: vector<u8> = b"cannot proccess newer tickets";
#[error]
const ENonZeroTotalSupply: vector<u8> = b"trying to give a token that has had some supply already minted";
#[error]
const ENotDistributor: vector<u8> = b"only the distributor can mint";
#[error]
const EUnregisteredCoin: vector<u8> = b"trying to find a coin that doesn't exist";
#[error]
const EUnregisteredCoinHasUrl: vector<u8> = b"the interchain token that is being registered has a URL";
#[error]
const EUntrustedAddress: vector<u8> = b"the sender that sent this message is not trusted";
#[error]
const EUntrustedChain: vector<u8> = b"the chain is not trusted";
#[error]
const EWrongDestination: vector<u8> = b"the channel trying to receive this call is not the destination";
const ITS_HUB_CHAIN_NAME: vector<u8> = [97, 120, 101, 108, 97, 114];
const ITS_HUB_ROUTING_IDENTIFIER: vector<u8> = [104, 117, 98];
const MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN: u256 = 1;
const MESSAGE_TYPE_INTERCHAIN_TRANSFER: u256 = 0;
const MESSAGE_TYPE_RECEIVE_FROM_HUB: u256 = 4;
const MESSAGE_TYPE_SEND_TO_HUB: u256 = 3;
new
public(friend) fun new(version_control: version_control::VersionControl, ctx: &mut tx_context::TxContext): interchain_token_service_v0::InterchainTokenService_v0
public(package) fun new(
version_control: VersionControl,
ctx: &mut TxContext,
): InterchainTokenService_v0 {
InterchainTokenService_v0 {
channel: axelar_gateway::channel::new(ctx),
address_tracker: address_tracker::new(
ctx,
),
registered_coins: bag::new(ctx),
registered_coin_types: table::new(ctx),
unregistered_coins: bag::new(ctx),
unregistered_coin_types: table::new(ctx),
relayer_discovery_id: object::id_from_address(@0x0),
version_control,
}
}
unregistered_coin_type
public(friend) fun unregistered_coin_type(self: &interchain_token_service_v0::InterchainTokenService_v0, symbol: &ascii::String, decimals: u8): &type_name::TypeName
public(package) fun unregistered_coin_type(
self: &InterchainTokenService_v0,
symbol: &String,
decimals: u8,
): &TypeName {
let key = token_id::unregistered_token_id(symbol, decimals);
assert!(self.unregistered_coin_types.contains(key), EUnregisteredCoin);
&self.unregistered_coin_types[key]
}
registered_coin_type
public(friend) fun registered_coin_type(self: &interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId): &type_name::TypeName
public(package) fun registered_coin_type(
self: &InterchainTokenService_v0,
token_id: TokenId,
): &TypeName {
assert!(self.registered_coin_types.contains(token_id), EUnregisteredCoin);
&self.registered_coin_types[token_id]
}
channel_address
public(friend) fun channel_address(self: &interchain_token_service_v0::InterchainTokenService_v0): address
public(package) fun channel_address(self: &InterchainTokenService_v0): address {
self.channel.to_address()
}
set_relayer_discovery_id
public(friend) fun set_relayer_discovery_id(self: &mut interchain_token_service_v0::InterchainTokenService_v0, relayer_discovery: &discovery::RelayerDiscovery)
public(package) fun set_relayer_discovery_id(
self: &mut InterchainTokenService_v0,
relayer_discovery: &RelayerDiscovery,
) {
self.relayer_discovery_id = object::id(relayer_discovery);
}
relayer_discovery_id
public(friend) fun relayer_discovery_id(self: &interchain_token_service_v0::InterchainTokenService_v0): object::ID
public(package) fun relayer_discovery_id(self: &InterchainTokenService_v0): ID {
self.relayer_discovery_id
}
set_trusted_address
public(friend) fun set_trusted_address(self: &mut interchain_token_service_v0::InterchainTokenService_v0, chain_name: ascii::String, trusted_address: ascii::String)
public(package) fun set_trusted_address(
self: &mut InterchainTokenService_v0,
chain_name: String,
trusted_address: String,
) {
self.address_tracker.set_trusted_address(chain_name, trusted_address);
}
remove_trusted_address
public(friend) fun remove_trusted_address(self: &mut interchain_token_service_v0::InterchainTokenService_v0, chain_name: ascii::String)
public(package) fun remove_trusted_address(
self: &mut InterchainTokenService_v0,
chain_name: String,
) {
self.address_tracker.remove_trusted_address(chain_name);
}
set_trusted_addresses
public(friend) fun set_trusted_addresses(self: &mut interchain_token_service_v0::InterchainTokenService_v0, trusted_addresses: trusted_addresses::TrustedAddresses)
public(package) fun set_trusted_addresses(
self: &mut InterchainTokenService_v0,
trusted_addresses: TrustedAddresses,
) {
let (chain_names, trusted_addresses) = trusted_addresses.destroy();
chain_names.zip_do!(
trusted_addresses,
|chain_name, trusted_address| self.set_trusted_address(
chain_name,
trusted_address,
),
);
}
remove_trusted_addresses
public(friend) fun remove_trusted_addresses(self: &mut interchain_token_service_v0::InterchainTokenService_v0, chain_names: vector<ascii::String>)
public(package) fun remove_trusted_addresses(
self: &mut InterchainTokenService_v0,
chain_names: vector<String>,
) {
chain_names.do!(
|chain_name| self.remove_trusted_address(
chain_name,
),
);
}
channel
public(friend) fun channel(self: &interchain_token_service_v0::InterchainTokenService_v0): &channel::Channel
public(package) fun channel(self: &InterchainTokenService_v0): &Channel {
&self.channel
}
version_control
public(friend) fun version_control(self: &interchain_token_service_v0::InterchainTokenService_v0): &version_control::VersionControl
public(package) fun version_control(self: &InterchainTokenService_v0): &VersionControl {
&self.version_control
}
register_coin
public(friend) fun register_coin<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, coin_info: coin_info::CoinInfo<T>, coin_management: coin_management::CoinManagement<T>): token_id::TokenId
public(package) fun register_coin<T>(
self: &mut InterchainTokenService_v0,
coin_info: CoinInfo<T>,
coin_management: CoinManagement<T>,
): TokenId {
let token_id = token_id::from_coin_data(&coin_info, &coin_management);
self.add_registered_coin(token_id, coin_management, coin_info);
token_id
}
deploy_remote_interchain_token
public(friend) fun deploy_remote_interchain_token<T>(self: &interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId, destination_chain: ascii::String): message_ticket::MessageTicket
public(package) fun deploy_remote_interchain_token<T>(
self: &InterchainTokenService_v0,
token_id: TokenId,
destination_chain: String,
): MessageTicket {
let coin_info = self.coin_info<T>(token_id);
let name = coin_info.name();
let symbol = coin_info.symbol();
let decimals = coin_info.decimals();
let mut writer = abi::new_writer(6);
writer
.write_u256(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN)
.write_u256(token_id.to_u256())
.write_bytes(*name.as_bytes())
.write_bytes(*symbol.as_bytes())
.write_u256((decimals as u256))
.write_bytes(vector::empty());
events::interchain_token_deployment_started<T>(
token_id,
name,
symbol,
decimals,
destination_chain,
);
prepare_message(self, destination_chain, writer.into_bytes())
}
send_interchain_transfer
public(friend) fun send_interchain_transfer<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, ticket: interchain_transfer_ticket::InterchainTransferTicket<T>, current_version: u64, clock: &clock::Clock): message_ticket::MessageTicket
public(package) fun send_interchain_transfer<T>(
self: &mut InterchainTokenService_v0,
ticket: InterchainTransferTicket<T>,
current_version: u64,
clock: &Clock,
): MessageTicket {
let (
token_id,
balance,
source_address,
destination_chain,
destination_address,
metadata,
version,
) = ticket.destroy();
assert!(version <= current_version, ENewerTicket);
let amount = self
.coin_management_mut(token_id)
.take_balance(balance, clock);
let (_version, data) = its_utils::decode_metadata(metadata);
let mut writer = abi::new_writer(6);
writer
.write_u256(MESSAGE_TYPE_INTERCHAIN_TRANSFER)
.write_u256(token_id.to_u256())
.write_bytes(source_address.to_bytes())
.write_bytes(destination_address)
.write_u256((amount as u256))
.write_bytes(data);
events::interchain_transfer<T>(
token_id,
source_address,
destination_chain,
destination_address,
amount,
&data,
);
self.prepare_message(destination_chain, writer.into_bytes())
}
receive_interchain_transfer
public(friend) fun receive_interchain_transfer<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, approved_message: channel::ApprovedMessage, clock: &clock::Clock, ctx: &mut tx_context::TxContext)
public(package) fun receive_interchain_transfer<T>(
self: &mut InterchainTokenService_v0,
approved_message: ApprovedMessage,
clock: &Clock,
ctx: &mut TxContext,
) {
let (source_chain, payload, message_id) = self.decode_approved_message(
approved_message,
);
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());
let source_address = reader.read_bytes();
let destination_address = address::from_bytes(reader.read_bytes());
let amount = read_amount(&mut reader);
let data = reader.read_bytes();
assert!(data.is_empty(), EInterchainTransferHasData);
let coin = self
.coin_management_mut(token_id)
.give_coin<T>(amount, clock, ctx);
transfer::public_transfer(coin, destination_address);
events::interchain_transfer_received<T>(
message_id,
token_id,
source_chain,
source_address,
destination_address,
amount,
&b"",
);
}
receive_interchain_transfer_with_data
public(friend) fun receive_interchain_transfer_with_data<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, approved_message: channel::ApprovedMessage, channel: &channel::Channel, clock: &clock::Clock, ctx: &mut tx_context::TxContext): (ascii::String, vector<u8>, vector<u8>, coin::Coin<T>)
public(package) fun receive_interchain_transfer_with_data<T>(
self: &mut InterchainTokenService_v0,
approved_message: ApprovedMessage,
channel: &Channel,
clock: &Clock,
ctx: &mut TxContext,
): (String, vector<u8>, vector<u8>, Coin<T>) {
let (source_chain, payload, message_id) = self.decode_approved_message(
approved_message,
);
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());
let source_address = reader.read_bytes();
let destination_address = address::from_bytes(reader.read_bytes());
let amount = read_amount(&mut reader);
let data = reader.read_bytes();
assert!(destination_address == channel.to_address(), EWrongDestination);
assert!(!data.is_empty(), EInterchainTransferHasNoData);
let coin = self.coin_management_mut(token_id).give_coin(amount, clock, ctx);
events::interchain_transfer_received<T>(
message_id,
token_id,
source_chain,
source_address,
destination_address,
amount,
&data,
);
(source_chain, source_address, data, coin)
}
receive_deploy_interchain_token
public(friend) fun receive_deploy_interchain_token<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, approved_message: channel::ApprovedMessage)
public(package) fun receive_deploy_interchain_token<T>(
self: &mut InterchainTokenService_v0,
approved_message: ApprovedMessage,
) {
let (_, payload, _) = self.decode_approved_message(approved_message);
let mut reader = abi::new_reader(payload);
assert!(
reader.read_u256() == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN,
EInvalidMessageType,
);
let token_id = token_id::from_u256(reader.read_u256());
let name = string::utf8(reader.read_bytes());
let symbol = ascii::string(reader.read_bytes());
let decimals = (reader.read_u256() as u8);
let distributor_bytes = reader.read_bytes();
let (treasury_cap, mut coin_metadata) = self.remove_unregistered_coin<T>(
token_id::unregistered_token_id(&symbol, decimals),
);
treasury_cap.update_name(&mut coin_metadata, name);
let mut coin_management = coin_management::new_with_cap<T>(treasury_cap);
let coin_info = coin_info::from_metadata<T>(coin_metadata);
if (distributor_bytes.length() > 0) {
let distributor = address::from_bytes(distributor_bytes);
coin_management.add_distributor(distributor);
};
self.add_registered_coin<T>(token_id, coin_management, coin_info);
}
give_unregistered_coin
public(friend) fun give_unregistered_coin<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, treasury_cap: coin::TreasuryCap<T>, coin_metadata: coin::CoinMetadata<T>)
public(package) fun give_unregistered_coin<T>(
self: &mut InterchainTokenService_v0,
treasury_cap: TreasuryCap<T>,
mut coin_metadata: CoinMetadata<T>,
) {
assert!(treasury_cap.total_supply() == 0, ENonZeroTotalSupply);
assert!(
coin::get_icon_url(&coin_metadata).is_none(),
EUnregisteredCoinHasUrl,
);
treasury_cap.update_description(&mut coin_metadata, string::utf8(b""));
let decimals = coin_metadata.get_decimals();
let symbol = coin_metadata.get_symbol();
let module_name = type_name::get_module(&type_name::get<T>());
assert!(
&module_name == &its_utils::module_from_symbol(&symbol),
EModuleNameDoesNotMatchSymbol,
);
let token_id = token_id::unregistered_token_id(&symbol, decimals);
self.add_unregistered_coin<T>(token_id, treasury_cap, coin_metadata);
events::unregistered_coin_received<T>(
token_id,
symbol,
decimals,
);
}
mint_as_distributor
public(friend) fun mint_as_distributor<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, channel: &channel::Channel, token_id: token_id::TokenId, amount: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>
public(package) fun mint_as_distributor<T>(
self: &mut InterchainTokenService_v0,
channel: &Channel,
token_id: TokenId,
amount: u64,
ctx: &mut TxContext,
): Coin<T> {
let coin_management = self.coin_management_mut<T>(token_id);
let distributor = channel.to_address();
assert!(coin_management.is_distributor(distributor), ENotDistributor);
coin_management.mint(amount, ctx)
}
mint_to_as_distributor
public(friend) fun mint_to_as_distributor<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, channel: &channel::Channel, token_id: token_id::TokenId, to: address, amount: u64, ctx: &mut tx_context::TxContext)
public(package) fun mint_to_as_distributor<T>(
self: &mut InterchainTokenService_v0,
channel: &Channel,
token_id: TokenId,
to: address,
amount: u64,
ctx: &mut TxContext,
) {
let coin_management = self.coin_management_mut<T>(token_id);
let distributor = channel.to_address();
assert!(coin_management.is_distributor(distributor), ENotDistributor);
let coin = coin_management.mint(amount, ctx);
transfer::public_transfer(coin, to);
}
burn_as_distributor
public(friend) fun burn_as_distributor<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, channel: &channel::Channel, token_id: token_id::TokenId, coin: coin::Coin<T>)
public(package) fun burn_as_distributor<T>(
self: &mut InterchainTokenService_v0,
channel: &Channel,
token_id: TokenId,
coin: Coin<T>,
) {
let coin_management = self.coin_management_mut<T>(token_id);
let distributor = channel.to_address();
assert!(coin_management.is_distributor<T>(distributor), ENotDistributor);
coin_management.burn(coin.into_balance());
}
set_flow_limit_as_token_operator
public(friend) fun set_flow_limit_as_token_operator<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, channel: &channel::Channel, token_id: token_id::TokenId, limit: u64)
public(package) fun set_flow_limit_as_token_operator<T>(
self: &mut InterchainTokenService_v0,
channel: &Channel,
token_id: TokenId,
limit: u64,
) {
self.coin_management_mut<T>(token_id).set_flow_limit(channel, limit);
events::flow_limit_set<T>(token_id, limit);
}
set_flow_limit
public(friend) fun set_flow_limit<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId, limit: u64)
public(package) fun set_flow_limit<T>(
self: &mut InterchainTokenService_v0,
token_id: TokenId,
limit: u64,
) {
self.coin_management_mut<T>(token_id).set_flow_limit_internal(limit);
events::flow_limit_set<T>(token_id, limit);
}
allow_function
public(friend) fun allow_function(self: &mut interchain_token_service_v0::InterchainTokenService_v0, version: u64, function_name: ascii::String)
public(package) fun allow_function(
self: &mut InterchainTokenService_v0,
version: u64,
function_name: String,
) {
self.version_control.allow_function(version, function_name);
}
disallow_function
public(friend) fun disallow_function(self: &mut interchain_token_service_v0::InterchainTokenService_v0, version: u64, function_name: ascii::String)
public(package) fun disallow_function(
self: &mut InterchainTokenService_v0,
version: u64,
function_name: String,
) {
self.version_control.disallow_function(version, function_name);
}
coin_data
fun coin_data<T>(self: &interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId): &coin_data::CoinData<T>
fun coin_data<T>(self: &InterchainTokenService_v0, token_id: TokenId): &CoinData<T> {
assert!(self.registered_coins.contains(token_id), EUnregisteredCoin);
&self.registered_coins[token_id]
}
coin_info
fun coin_info<T>(self: &interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId): &coin_info::CoinInfo<T>
fun coin_info<T>(self: &InterchainTokenService_v0, token_id: TokenId): &CoinInfo<T> {
coin_data<T>(self, token_id).coin_info()
}
is_trusted_address
fun is_trusted_address(self: &interchain_token_service_v0::InterchainTokenService_v0, source_chain: ascii::String, source_address: ascii::String): bool
fun is_trusted_address(
self: &InterchainTokenService_v0,
source_chain: String,
source_address: String,
): bool {
self.address_tracker.is_trusted_address(source_chain, source_address)
}
coin_management_mut
fun coin_management_mut<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId): &mut coin_management::CoinManagement<T>
fun coin_management_mut<T>(
self: &mut InterchainTokenService_v0,
token_id: TokenId,
): &mut CoinManagement<T> {
let coin_data: &mut CoinData<T> = &mut self.registered_coins[token_id];
coin_data.coin_management_mut()
}
add_unregistered_coin
fun add_unregistered_coin<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::UnregisteredTokenId, treasury_cap: coin::TreasuryCap<T>, coin_metadata: coin::CoinMetadata<T>)
fun add_unregistered_coin<T>(
self: &mut InterchainTokenService_v0,
token_id: UnregisteredTokenId,
treasury_cap: TreasuryCap<T>,
coin_metadata: CoinMetadata<T>,
) {
self
.unregistered_coins
.add(
token_id,
unregistered_coin_data::new(
treasury_cap,
coin_metadata,
),
);
let type_name = type_name::get<T>();
add_unregistered_coin_type(self, token_id, type_name);
}
remove_unregistered_coin
fun remove_unregistered_coin<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::UnregisteredTokenId): (coin::TreasuryCap<T>, coin::CoinMetadata<T>)
fun remove_unregistered_coin<T>(
self: &mut InterchainTokenService_v0,
token_id: UnregisteredTokenId,
): (TreasuryCap<T>, CoinMetadata<T>) {
let unregistered_coins: UnregisteredCoinData<T> = self
.unregistered_coins
.remove(token_id);
let (treasury_cap, coin_metadata) = unregistered_coins.destroy();
remove_unregistered_coin_type(self, token_id);
(treasury_cap, coin_metadata)
}
trusted_address
fun trusted_address(self: &interchain_token_service_v0::InterchainTokenService_v0, chain_name: ascii::String): ascii::String
fun trusted_address(self: &InterchainTokenService_v0, chain_name: String): String {
*self.address_tracker.trusted_address(chain_name)
}
add_unregistered_coin_type
fun add_unregistered_coin_type(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::UnregisteredTokenId, type_name: type_name::TypeName)
fun add_unregistered_coin_type(
self: &mut InterchainTokenService_v0,
token_id: UnregisteredTokenId,
type_name: TypeName,
) {
self.unregistered_coin_types.add(token_id, type_name);
}
remove_unregistered_coin_type
fun remove_unregistered_coin_type(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::UnregisteredTokenId): type_name::TypeName
fun remove_unregistered_coin_type(
self: &mut InterchainTokenService_v0,
token_id: UnregisteredTokenId,
): TypeName {
self.unregistered_coin_types.remove(token_id)
}
add_registered_coin_type
fun add_registered_coin_type(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId, type_name: type_name::TypeName)
fun add_registered_coin_type(
self: &mut InterchainTokenService_v0,
token_id: TokenId,
type_name: TypeName,
) {
self.registered_coin_types.add(token_id, type_name);
}
add_registered_coin
fun add_registered_coin<T>(self: &mut interchain_token_service_v0::InterchainTokenService_v0, token_id: token_id::TokenId, coin_management: coin_management::CoinManagement<T>, coin_info: coin_info::CoinInfo<T>)
fun add_registered_coin<T>(
self: &mut InterchainTokenService_v0,
token_id: TokenId,
coin_management: CoinManagement<T>,
coin_info: CoinInfo<T>,
) {
self
.registered_coins
.add(
token_id,
coin_data::new(
coin_management,
coin_info,
),
);
let type_name = type_name::get<T>();
add_registered_coin_type(self, token_id, type_name);
events::coin_registered<T>(
token_id,
);
}
prepare_message
Send a payload to a destination chain. The destination chain needs to have a trusted address.
fun prepare_message(self: &interchain_token_service_v0::InterchainTokenService_v0, destination_chain: ascii::String, payload: vector<u8>): message_ticket::MessageTicket
fun prepare_message(
self: &InterchainTokenService_v0,
mut destination_chain: String,
mut payload: vector<u8>,
): MessageTicket {
let mut destination_address = self.trusted_address(destination_chain);
// Prevent sending directly to the InterchainTokenService Hub chain. This is not supported yet,
// so fail early to prevent the user from having their funds stuck.
assert!(
destination_chain.into_bytes() != ITS_HUB_CHAIN_NAME,
EUntrustedChain,
);
// Check whether the InterchainTokenService call should be routed via InterchainTokenService hub for this
// destination chain
if (destination_address.into_bytes() == ITS_HUB_ROUTING_IDENTIFIER) {
let mut writer = abi::new_writer(3);
writer.write_u256(MESSAGE_TYPE_SEND_TO_HUB);
writer.write_bytes(destination_chain.into_bytes());
writer.write_bytes(payload);
payload = writer.into_bytes();
destination_chain = ascii::string(ITS_HUB_CHAIN_NAME);
destination_address = self.trusted_address(destination_chain);
};
gateway::prepare_message(
&self.channel,
destination_chain,
destination_address,
payload,
)
}
decode_approved_message
Decode an approved call and check that the source chain is trusted.
fun decode_approved_message(self: &interchain_token_service_v0::InterchainTokenService_v0, approved_message: channel::ApprovedMessage): (ascii::String, vector<u8>, ascii::String)
fun decode_approved_message(
self: &InterchainTokenService_v0,
approved_message: ApprovedMessage,
): (String, vector<u8>, String) {
let (mut source_chain, message_id, source_address, mut payload) = self
.channel
.consume_approved_message(approved_message);
assert!(
self.is_trusted_address(source_chain, source_address),
EUntrustedAddress,
);
let mut reader = abi::new_reader(payload);
if (reader.read_u256() == MESSAGE_TYPE_RECEIVE_FROM_HUB) {
assert!(
source_chain.into_bytes() == ITS_HUB_CHAIN_NAME,
EUntrustedChain,
);
source_chain = ascii::string(reader.read_bytes());
payload = reader.read_bytes();
assert!(
self.trusted_address(source_chain).into_bytes() == ITS_HUB_ROUTING_IDENTIFIER,
EUntrustedChain,
);
} else {
assert!(
source_chain.into_bytes() != ITS_HUB_CHAIN_NAME,
EUntrustedChain,
);
};
(source_chain, payload, message_id)
}
read_amount
fun read_amount(reader: &mut abi::AbiReader): u64
fun read_amount(reader: &mut AbiReader): u64 {
let amount = std::macros::try_as_u64!(reader.read_u256());
assert!(amount.is_some(), EOverflow);
amount.destroy_some()
}