Docs
IntegrationsSolana

ITS Program Reference

The Solana ITS program: accounts, PDAs, instructions and events.

The ITS program is an Anchor program, published as the solana-axelar-its crate. Its address on each network is on Chains and contracts; the crate's network feature (mainnet or testnet) sets it as solana_axelar_its::ID. See Setup.

Accounts

ITS root

The ITS root PDA (InterchainTokenService) holds the program's configuration:

pub struct InterchainTokenService {
    pub its_hub_address: String,
    pub chain_name: String,
    pub paused: bool,
    pub trusted_chains: Vec<String>,
    pub bump: u8,
}

ITS sends and accepts transfers only for chains in trusted_chains, and only messages from the ITS Hub at its_hub_address.

Token manager

Each token has a TokenManager PDA, which is the authority of the token's mint for mint and burn types, and of the token account that holds locked tokens for lock and unlock types:

pub struct TokenManager {
    pub ty: Type,
    pub token_id: [u8; 32],
    pub token_address: Pubkey,             // the mint
    pub associated_token_account: Pubkey,  // the token manager's token account
    pub flow_slot: FlowState,
    pub bump: u8,
}

pub struct FlowState {
    pub flow_limit: Option<u64>,
    pub flow_in: u64,
    pub flow_out: u64,
    pub epoch: u64, // the 6-hour window that flow_in and flow_out count
}

Type has the same values as the token manager types on other chains: NativeInterchainToken (0), MintBurnFrom (1), LockUnlock (2), LockUnlockFee (3) and MintBurn (4). On Solana, MintBurnFrom burns like MintBurn, with the sender's signature.

Roles

A UserRoles PDA holds an account's roles on a token manager, or on ITS itself for ITS's operator, as a bitmask: MINTER (0x01), OPERATOR (0x02) and FLOW_LIMITER (0x04). See Roles.

PDAs

SeedsProgramAccount
b"interchain-token-service"ITSITS root
b"token-manager", ITS root, token IDITSToken manager of a token
b"interchain-token", ITS root, token IDITSMint of an interchain token that ITS deployed
b"user-roles", token manager or ITS root, accountITSAn account's roles
b"interchain-transfer-execute", your program IDITSSigner that ITS uses to call your program
b"axelar-its-token-authority"Your programAuthority of the token account that receives your program's tokens

The token manager's token account is its associated token account for the mint. The crate exposes the seeds in solana_axelar_its::seed_prefixes, and find_pda functions on InterchainTokenService, TokenManager and UserRoles.

Deriving the accounts

The accounts of interchain_transfer, derived off-chain with the ITS, Gateway and Gas Service crates:

use anchor_spl::associated_token::get_associated_token_address_with_program_id;
use solana_axelar_its::{InterchainTokenService, TokenManager};

fn interchain_transfer_accounts(
    token_id: [u8; 32],
    token_mint: Pubkey,
    token_program: Pubkey,
    sender: Pubkey,
) {
    let its_root_pda = InterchainTokenService::find_pda().0;
    let its_event_authority = solana_axelar_its::EVENT_AUTHORITY_AND_BUMP.0;
    let token_manager_pda = TokenManager::find_pda(token_id, its_root_pda).0;
    let token_manager_ata =
        get_associated_token_address_with_program_id(&token_manager_pda, &token_mint, &token_program);
    let sender_token_account =
        get_associated_token_address_with_program_id(&sender, &token_mint, &token_program);

    let gateway_root_pda = solana_axelar_gateway::GatewayConfig::find_pda().0;
    let gateway_event_authority = solana_axelar_gateway::EVENT_AUTHORITY_AND_BUMP.0;
    // ITS's signing PDA for the gateway, derived from the ITS program ID
    let call_contract_signing_pda =
        solana_axelar_gateway::CallContractSigner::find_pda(&solana_axelar_its::ID).0;

    let gas_treasury = Pubkey::find_program_address(
        &[solana_axelar_gas_service::state::Treasury::SEED_PREFIX],
        &solana_axelar_gas_service::ID,
    )
    .0;
    let gas_event_authority = solana_axelar_gas_service::EVENT_AUTHORITY_AND_BUMP.0;
}

The token's mint is TokenManager::find_token_mint for an interchain token that ITS deployed, and the existing mint for a canonical or custom token. token_program is the mint's owner: the SPL Token or the Token-2022 program.

Instructions

InstructionSigned byDoes
interchain_transferThe token ownerSends tokens, with optional data. See Send tokens
deploy_interchain_tokenThe deployerDeploys an interchain token on Solana
deploy_remote_interchain_tokenThe deployerDeploys it to another chain
register_canonical_interchain_tokenAnyoneRegisters an existing mint as a canonical token
deploy_remote_canonical_interchain_tokenAnyoneDeploys a canonical token to another chain
register_token_metadataAnyoneSends a mint's decimals to the ITS Hub
register_custom_tokenThe deployerCreates the token manager of a custom token
link_tokenThe deployerLinks a custom token to a token on another chain
handover_mint_authorityThe mint authorityGives the token manager the mint authority, and the signer MINTER
mint_interchain_tokenA minterMints the token
transfer_interchain_token_mintershipA minterPasses on MINTER
add_token_manager_flow_limiterThe token manager's operatorGives an account FLOW_LIMITER
remove_token_manager_flow_limiterThe token manager's operatorRemoves FLOW_LIMITER from an account
transfer_token_manager_operatorshipThe token manager's operatorPasses on OPERATOR
set_token_manager_flow_limitA flow limiterSets the token's flow limit
set_flow_limitITS's operatorSets any token's flow limit

ITS's operator, or the program's upgrade authority, manages the trusted chains (set_trusted_chain, remove_trusted_chain). The upgrade authority can pause ITS (set_pause_status). The relayer calls execute for messages from the ITS Hub, and ITS then calls execute_interchain_transfer, execute_deploy_interchain_token or execute_link_token on itself.

Events

ITS emits Anchor events through CPI (events.rs):

EventWhen
InterchainTransferSentA transfer leaves Solana
InterchainTransferReceivedA transfer arrives on Solana
InterchainTokenDeployedITS deploys an interchain token on Solana
InterchainTokenDeploymentStartedA token is deployed from Solana to another chain
TokenManagerDeployedITS creates a token manager on Solana
TokenMetadataRegisteredA mint's decimals are sent to the ITS Hub
LinkTokenStartedA custom token is linked from Solana to another chain
FlowLimitSetA token's flow limit changes
TrustedChainSet, TrustedChainRemovedITS's trusted chains change

The transfer events carry the token ID, the source or destination address and chain, the amount after any fee, and the hash of the data, if any:

pub struct InterchainTransferSent {
    pub token_id: [u8; 32],
    pub source_address: Pubkey,
    pub source_token_account: Pubkey,
    pub destination_chain: String,
    pub destination_address: Vec<u8>,
    pub amount: u64,
    pub data_hash: Option<[u8; 32]>,
}

pub struct InterchainTransferReceived {
    pub command_id: [u8; 32],
    pub token_id: [u8; 32],
    pub source_chain: String,
    pub source_address: Vec<u8>,
    pub destination_address: Pubkey,
    pub destination_token_account: Pubkey,
    pub amount: u64,
    pub data_hash: Option<[u8; 32]>,
}

Support

On this page