--- title: Callbacks sidebar_label: Callbacks sidebar_position: 4 slug: /contract-api/callbacks --- # Callbacks The `cw-ica-controller` contract provides a callback mechanism upon various channel and packet lifecycle events. A callback address is recorded in the contract's state. This address is set during the contract's instantiation or can be updated later by the contract owner using [`ExecuteMsg::UpdateCallbackAddress`](./02-execute-msg.mdx#updatecallbackaddress). ## `ReceiveIcaCallback` enum variant The contract whose address is recorded as the callback address must include a callback enum variant in its `ExecuteMsg` enum. We included a procedural macro to generate this enum variant for you in `cw-ica-controller`'s `helpers` module. See the following example: ```rust title="src/msg.rs" use cw_ica_controller::helpers::ica_callback_execute; #[ica_callback_execute] #[cw_serde] pub enum ExecuteMsg {} ``` This will transform the enum to: ```rust title="src/msg.rs" #[cw_serde] pub enum ExecuteMsg { ReceiveIcaCallback(::cw_ica_controller::types::callbacks::IcaControllerCallbackMsg), } ``` :::note Other derive macro invocations must occur after this procedural macro as they may depend on the new variant. For example, the following will **fail** because the `Clone` derivation occurs before the addition of the field. ```rust use cw_ica_controller::helper::ica_callback_execute; use cosmwasm_schema::cw_serde; #[derive(Clone)] #[ica_callback_execute] #[allow(dead_code)] #[cw_serde] enum Test { Foo, Bar(u64), Baz { foo: u64 }, } ``` ::: Since this variant is inserted to the `ExecuteMsg`, the callback contract must handle this enum variant in its `execute` function: ```rust reference https://github.com/srdtrk/cw-ica-controller/blob/v0.4.1/testing/contracts/callback-counter/src/contract.rs#L28-L40 ``` The callback contract can then handle the callback message as it sees fit, ideally by performing some kind of validation that the callback comes from an expected legitimate source. The callback contract can also perform some kind of action based on the callback message, such as incrementing a counter or error handling. :::warning If the callback contract returns an error, the `cw-ica-controller` will not proceed with the channel or packet lifecycle event that triggered the callback. 1. If the callback contract returns an error in response to a `ChannelOpenAck` callback, then the `cw-ica-controller` will not proceed with the channel opening. 2. If the callback contract returns an error in response to a `OnAcknowledgementPacketCallback` callback, then the `cw-ica-controller` will not proceed with the packet acknowledgement. 3. If the callback contract returns an error in response to a `OnTimeoutPacketCallback` callback, then the `cw-ica-controller` will not proceed with the packet timeout. If the ICA channel is ordered, cases 2 and 3 will result in the halting of the channel until the callback contract returns a successful response. ::: ## IcaControllerCallbackMsg The `IcaControllerCallbackMsg` enum is the message type that is sent to the callback contract. It contains the following variants: ```rust reference https://github.com/srdtrk/cw-ica-controller/blob/7773fbd8d4e227b6c942f0c88575f9800809b4bf/src/types/callbacks.rs#L15-L59 ``` ### OnChannelOpenAckCallback The `OnChannelOpenAckCallback` variant is sent to the callback contract when the `cw-ica-controller` receives a `ChannelOpenAck` message from the counterparty chain. Let's go through the fields of this variant: - **`channel`**: This is the IBC Channel that would be opened if the callback contract returns a successful response. See [`cosmwasm_std::IbcChannel`](https://github.com/CosmWasm/cosmwasm/blob/v1.5.2/packages/std/src/ibc.rs#L115-L128) for more details. - **`ica_address`**: This is the address (in the counterparty chain) of the interchain account that would be created if the callback contract returns a successful response. - **`tx_encoding`**: This is the transaction encoding that would be used for the ICS-27 transactions. ### OnAcknowledgementPacketCallback The `OnAcknowledgementPacketCallback` variant is sent to the callback contract when the `cw-ica-controller` receives an acknowledgement packet from the counterparty chain for a packet that was sent from the calling `cw-ica-controller` contract. Let's go through the fields of this variant: - **`ica_acknowledgement`**: This is the acknowledgement data that was sent by the counterparty chain. ```rust reference https://github.com/srdtrk/cw-ica-controller/blob/v0.4.1/src/ibc/types/packet.rs#L169-L177 ``` If the ICA packet was successfully executed on the counterparty chain, then this will be `Data::Result(Binary)` where `Binary` is the protobuf encoded result of the ICA packet execution. If the ICA packet was not successfully executed on the counterparty chain, then this will be `Data::Error(String)` where `String` is the error message returned by the counterparty chain. :::note The error message returned by the counterparty chain doesn't include any useful information about the error. It only contains the codespace of the error. This is because in CosmosSDK, tx error messages may be non-deterministic, and thus, they cannot be included in the IBC packet acknowledgement which is a deterministic message. This is a limitation of `ibc-go`. ::: - **`original_packet`**: This is the original ICA packet that was sent by the calling `cw-ica-controller` contract. See [`cosmwasm_std::IbcPacket`](https://github.com/CosmWasm/cosmwasm/blob/v1.5.2/packages/std/src/ibc.rs#L195-L207) - **`relayer`**: This is the address of the relayer that relayed the packet to the counterparty chain. - **`query_result`**: This is the result of the queries that were executed on the counterparty chain. This is only present if the packet contained queries. See [`IcaQueryResult`](https://github.com/srdtrk/cw-ica-controller/blob/7773fbd8d4e227b6c942f0c88575f9800809b4bf/src/types/query_msg.rs#L93-L106) ### OnTimeoutPacketCallback The `OnTimeoutPacketCallback` variant is sent to the callback contract when the `cw-ica-controller` receives a timeout packet for a packet that was sent. Let's go through the fields of this variant: - **`original_packet`**: This is the original ICA packet that was sent by the calling `cw-ica-controller` contract. See [`cosmwasm_std::IbcPacket`](https://github.com/CosmWasm/cosmwasm/blob/v1.5.2/packages/std/src/ibc.rs#L195-L207) - **`relayer`**: This is the address of the relayer that relayed the packet to the counterparty chain.