iba
Accounts on chains, owned by accounts on another chain.
Interchain Bitsong Accounts
Setting Up An IBA
Users must install the ibc-client
contract on their account to enable IBC. To do so they can call the ExecuteMsg::InstallModules
endpoint with the abstract:ibc-client
module ID.
(Optional) Create an account on the remote chain
After the initialization step, the account is ready to send messages across IBC. However, if you wish, you can customize the remote account metadata before sending any messages. The following message is executed on the account
contract:
pub enum AccountExecuteMsg {
ExecuteOnModule {
module_id: "abstract:ibc-client",
exec_msg: IbcClientExecuteMsg {
Register {
host_chain: "destination-chain",
// Customizable parameters
base_asset: None,
namespace: None,
install_modules: vec![],
},
...,
}
}
...,
}
Account ID structure
The remote Interchain IBA Account will have the same account sequence but will have a different trace. Let’s take an example. A account on Bitsong with account sequence 69 wants to create accounts on Osmosis and Stargaze.
Their account ID on Bitsong is
local-69
.Their account ID on Osmosis is
bitsong-69
.Their account ID on Stargaze is
bitsong-69
as well!
Remote accounts can create other remote accounts, and their traces will be chained. For instance, the bitsong-69
account on Osmosis can create an account on Stargaze which will have the ID bitsong>osmosis-69
. This gives the ability to trace ICAAs back to their origin chain.
For a even more complex example, a bitsong account that was created on Osmosis to Stargaze to Neutron to Juno, the account id on Juno would be
osmosis>stargaze>neutron>-bitsong-69
.
Sending messages on remote accounts
With or without a pre-existing remote Account, Abstract Accounts are able to send messages on remote Accounts. The account_msgs
will be executed in order on the remote account.
pub enum AccountExecuteMsg {
ExecuteOnModule {
module_id: "abstract:ibc-client",
exec_msg: IbcClientExecuteMsg {
RemoteAction{
host_chain: "destination-chain",
action: HostAction{
Dispatch{
account_msgs: Vec<AccountExecuteMsg { ... }>
},
...,
}
},
...,
}
}
...,
}
Note that the two instances of the AccountExecuteMsg
enum are the exact same type. This allows you to send multi-hop IBC messages. However, multi-hop transactions (of these kind) are not really something you would use often, unless you’re using another chain as a routing chain.
Specification of Interchain Bitsong Accounts
It is recommended to review the technical specification for the Abstract Account framework here. We will review the primary components in these documentation.
General mechanism
IBC capabilities for accounts are allowed by the ibc-client<->ibc-host
pair. The ibc-client
is responsible for authenticating the sender and sending packets across IBC to the ibc-host
. The ibc-host
is responsible for receiving packets and routing the packet to the corresponding contract on the remote chain. Under the hood, the client-host
connection is handled by a Polytone channel. This allows IBA Accounts to be interoperable with other protocols, more resilient to IBC constraints.
You see that an IBA Interchain connection is uni-directional. You need 2 connections to be able to interact bi-directionnally with an account. Up until today however, only a local account can act on a distant account and not the other way around. Here is an examples using AccountId between bitsong and osmosis:
local-69
on bitsong CAN controlbitsong-69
on osmosis via IBCbitsong-69
on osmosis CAN’T controllocal-69
on bitsong
Account creation
IBA Accounts are traditional Bitsong Abstracts Accounts controlled by the ibc-host
. The ibc-host
is the admin of the account and routes any packet sent by a remote account on the corresponding local account. When creating an account, it is simply registered by the ibc-host
using the account-factory just like any other account.
When an action is triggered by a remote account, the ibc-host
does the following verifications:
If an local account already exists on-chain for the remote account, it just dispatches the message to the account.
If no account exists, it creates one with default metadata and THEN dispatches the messages to this new account.
The Account creation process is therefore not mandatory when interacting with IBA Accounts. This is why when you create an Bitsong Abstract Account, you automatically have an account on every connected chains!
Data Structures
Interchain Bitsong Account communication is done via a single message structure:
pub enum IbcHostExecuteMsg{
/// Allows for remote execution from the Polytone implementation
#[cw_orch(fn_name("ibc_execute"))]
Execute {
account_id: AccountId,
/// The address of the calling account id. This is used purely for the send-all-back method.
/// We include it in all messages none-the-less to simplify the users life
account_address: String,
action: HostAction,
},
...,
}
account-id
is the id of the local account calling the action.account_address
is the address of the local account calling the action.action
is the action that should be executed by the ibc-host on the remote account:
/// Callable actions on a remote host
#[cosmwasm_schema::cw_serde]
pub enum HostAction {
/// Dispatch messages to a remote Account.
/// Will create a new Account if required.
Dispatch {
account_msgs: Vec<account::ExecuteMsg>,
},
/// Can't be called by an account directly. These are permissioned messages that only the IBC Client is allowed to call by itself.
Internal(InternalAction),
/// Some helpers that allow calling dispatch messages faster (for actions that are called regularly)
Helpers(HelperAction),
}
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum InternalAction {
/// Registers a new account from a remote chain
Register {
name: Option<String>,
description: Option<String>,
link: Option<String>,
namespace: Option<String>,
install_modules: Vec<ModuleInstallConfig>,
},
}
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum HelperAction {
SendAllBack,
}
Acknowledgement and Callback
IBC works with 4 steps:
Sending a packet (Source chain)
Receiving a packet (Destination chain)
Sending an acknowledgement (Destination chain)
Receiving an acknowledgement (Source chain)
We have already covered the 2 first steps with the sections above. We cover the 2 lasts steps in this section.
Step 3 (sending an ack), is handled by Polytone. They catch any error that could happen during contract execution and send back an acknowledgement reflecting the state of the contract execution on the remote chain. This is handled through the Callback struct.
For Step 4, Polytone allows for sending a message to the initial sender of the IBC interaction after the packet was successfully received in the remote chain. Abstract DOESN’T use this feature for user actions, so callbacks are not possible when using Interchain Abstract Accounts. If you are a module developer, check out the Module IBC section that allows for callbacks.
Cross chain trace
Because accounts created across chains using the IBA protocol are controlled by an account located on a remote chain, the account that is calling the action needs to be related to the account on the remote chain. This is done through the AccountId struct. The IBC-host module leverages the AccountId::trace
field of this struct. An account is either AccountTrace::Local
or AccountTrace::Remote
. When a PacketMsg
is sent across an IBC channel, the account id is transformed on the receiving chain in the following manner:
If it was
AccountTrace::Local
before transfer, it turns into anAccountTrace::Remote
account with one chain in the associated vector being the chain calling thePacketMsg
(PacketMsg::client_chain)
If it was
AccountTrace::Remote
before transfer, it stays remote and the client_chain field is pushed to the associated vector.
This allows full traceability of the account creations and calls.
Last updated