diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca85931d..495a1761 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## [Unreleased]
+## v0.6.0 (2024-06-18)
+
### Features
- Added support for ICA queries. (https://github.com/srdtrk/cw-ica-controller/issues/88)
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 4aaf7dd2..9bb11bb9 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -1,5 +1,5 @@
-import {themes as prismThemes} from 'prism-react-renderer';
-import type {Config} from '@docusaurus/types';
+import { themes as prismThemes } from 'prism-react-renderer';
+import type { Config } from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
const config: Config = {
@@ -43,13 +43,17 @@ const config: Config = {
routeBasePath: "/",
sidebarCollapsed: false,
// Select the latest version
- lastVersion: "v0.5.x",
+ lastVersion: "v0.6.x",
versions: {
current: {
label: 'main',
path: 'main',
banner: 'unreleased',
},
+ "v0.6.x": {
+ label: 'v0.6.x',
+ path: 'v0.6',
+ },
"v0.5.x": {
label: 'v0.5.x',
path: 'v0.5',
@@ -158,10 +162,10 @@ const config: Config = {
},
// github codeblock theme configuration
codeblock: {
- showGithubLink: true,
- githubLinkLabel: 'View on GitHub',
- showRunmeLink: false,
- runmeLinkLabel: 'Checkout via Runme'
+ showGithubLink: true,
+ githubLinkLabel: 'View on GitHub',
+ showRunmeLink: false,
+ runmeLinkLabel: 'Checkout via Runme'
},
} satisfies Preset.ThemeConfig,
plugins: [
diff --git a/docs/versioned_docs/version-v0.6.x/00-intro.mdx b/docs/versioned_docs/version-v0.6.x/00-intro.mdx
new file mode 100644
index 00000000..e400a8e5
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/00-intro.mdx
@@ -0,0 +1,43 @@
+---
+title: Introduction
+sidebar_label: Introduction
+sidebar_position: 0
+slug: /
+---
+
+import HighlightTag from '@site/src/components/HighlightTag';
+
+# CosmWasm ICA Controller
+
+
+
+Welcome to the documentation for CosmWasm Interchain Accounts Controller. This document will guide you through
+understanding the [ICS-27](https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts)
+Interchain Accounts protocol and how to use `cw-ica-controller` to create and manage interchain accounts on
+any IBC enabled CosmWasm chain.
+
+The CosmWasm ICA Controller is a CosmWasm contract that implements the ICS-27 interchain accounts controller in
+pure Rust. It is designed to be used by other CosmWasm contracts to create and manage interchain accounts on
+the chain where the contract is deployed.
+
+## High Level Overview
+
+The following diagram shows how `cw-ica-controller` works at a high level.
+
+![High Level Overview](/img/cw-ica-controller.svg)
+
+The `cw-ica-controller` contract code is deployed on a chain that supports IBC CosmWasm. This chain does not need
+to support ICS-27 interchain accounts nor does it need to support any custom IBC bindings. Then when an external
+account or a contract instantiates a `cw-ica-controller` contract, the contract will initiate the ICS-27 handshake
+with a chain that supports ICS-27 interchain accounts based on the options provided by the caller.
+
+:::note
+
+The counterparty chain need not be a CosmWasm chain. It can be any chain that uses ibc-go and supports `ICS-27`.
+Such as CosmosHub, Osmosis, etc.
+
+:::
+
+Then the rest of the ICS-27 handshake is completed by the relayers automatically. Both the hermes relayer and the
+go relayer support `ICS-27` interchain accounts. Once the handshake is complete, the `cw-ica-controller` contract
+makes a callback to the callback contract if one was provided during instantiation.
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/00-intro.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/00-intro.mdx
new file mode 100644
index 00000000..6a3c519c
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/00-intro.mdx
@@ -0,0 +1,22 @@
+---
+title: Contract API
+sidebar_label: Overview
+sidebar_position: 0
+slug: /contract-api/intro
+---
+
+import HighlightTag from '@site/src/components/HighlightTag';
+
+# Contract API
+
+
+
+In this section we will cover how to interact with the contract and design decisions that were made. A full integration guide is work in progress.
+
+In this section, we cover the following topics:
+
+- ✉️ [`InstantiateMsg`](./01-instantiate-msg.mdx)
+- 📨 [`ExecuteMsg`](./02-execute-msg.mdx)
+- 🤔 [`QueryMsg`](./03-query-msg.mdx)
+- 🤙 [Callbacks](./04-callbacks.mdx)
+- 📜 [Events](./05-events.mdx)
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/01-instantiate-msg.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/01-instantiate-msg.mdx
new file mode 100644
index 00000000..c1f6b7bf
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/01-instantiate-msg.mdx
@@ -0,0 +1,58 @@
+---
+title: InstantiateMsg
+sidebar_label: InstantiateMsg
+sidebar_position: 1
+slug: /contract-api/instantiate-msg
+---
+
+# `InstantiateMsg`
+
+The `InstantiateMsg` is the message that is used to instantiate the `cw-ica-controller` contract.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/msg.rs#L8-L21
+```
+
+## Fields
+
+### `owner`
+
+This contract has an owner who is allowed to call the `ExecuteMsg` methods.
+The owner management is handled by the amazing [cw-ownable](https://crates.io/crates/cw-ownable) crate.
+If left empty, the owner is set to the sender of the `InstantiateMsg`.
+
+### `channel_open_init_options`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/6843b80b29af97b9c4561ad487420e2f54857553/src/types/msg.rs#L95-L107
+```
+
+These are the options required for the contract to initiate an ICS-27 channel open handshake.
+This contract requires there to be an IBC connection between the two chains before it can open a channel.
+
+#### `connection_id`
+
+The identifier of the IBC connection end on the deployed (source) chain. (The underlying IBC light client must
+be live.) If this field is set to a non-existent connection, the execution of the `InstantiateMsg` will fail.
+
+#### `counterparty_connection_id`
+
+The identifier of the IBC connection end on the counterparty (destination) chain. (The underlying IBC light
+client must be live.) If this field is set to a non-existent connection or a different connection's end,
+then the execution of the `InstantiateMsg` will not fail. This is because the source chain does not know
+about the counterparty chain's connections. Instead, the channel open handshake will fail to complete.
+
+If the contract was instantiated with a `counterparty_connection_id` that does not match the connection
+end on the counterparty chain, then the owner must call [`ExecuteMsg::CreateChannel`](./02-execute-msg.mdx#createchannel) with the correct parameters to start a new channel open handshake.
+
+#### `counterparty_port_id`
+
+This is a required parameter for the ICS-27 channel version metadata. I've added it here for consistency.
+Currently, the only supported value is `icahost`. If left empty, it is set to `icahost`.
+**So you should ignore this field.**
+
+### `send_callbacks_to`
+
+This is the address of the contract that will receive the callbacks from the `cw-ica-controller` contract.
+This may be the same address as the `owner` or a different address. If left empty, no callbacks will be sent.
+Learn more about callbacks [here](./04-callbacks.mdx).
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/02-execute-msg.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/02-execute-msg.mdx
new file mode 100644
index 00000000..d05dd6eb
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/02-execute-msg.mdx
@@ -0,0 +1,151 @@
+---
+title: ExecuteMsg
+sidebar_label: ExecuteMsg
+sidebar_position: 2
+slug: /contract-api/execute-msg
+---
+
+# `ExecuteMsg`
+
+The `ExecuteMsg` is the message that is used to interact with the `cw-ica-controller` contract.
+**All execute messages are only callable by the owner of the contract.**
+
+## `CreateChannel`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/7773fbd8d4e227b6c942f0c88575f9800809b4bf/src/types/msg.rs#L29-L39
+```
+
+This message is used to initiate an ICS-27 channel open handshake. It is only callable by the owner.
+This message only takes one optional parameter: `channel_open_init_options`.
+
+If this parameter is left empty, then the contract will use the `channel_open_init_options` that were last
+passed to the `InstantiateMsg` or `CreateChannel` messages.
+
+If this parameter is set, then the contract will use the `channel_open_init_options` that are passed to this
+message and save them for future `CreateChannel` messages.
+
+## `CloseChannel`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/7773fbd8d4e227b6c942f0c88575f9800809b4bf/src/types/msg.rs#L40-L41
+```
+
+This message is used to close the ICS-27 channel. It is only callable by the owner.
+The channel can then be reopened with parameters (e.g. channel ordering and version) that are different from the
+original channel open handshake.
+
+## `SendCosmosMsgs`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/7773fbd8d4e227b6c942f0c88575f9800809b4bf/src/types/msg.rs#L42-L64
+```
+
+Once an ICS-27 channel open handshake is complete, the owner can control the interchain account on the counterparty
+chain. To give the owner a familiar interface, this message allows the owner to take actions with the interchain
+account using `CosmosMsg`s. This is the recommended way to use the interchain account. We will go over the fields of
+this message in detail.
+
+### `messages`
+
+This is a list of `CosmosMsg`s that the contract will execute on the counterparty chain using the interchain account.
+This execution is atomic. If any of the `CosmosMsg`s fail, then the entire execution will fail.
+
+:::note
+
+All applicable `CosmosMsg`s are supported if the channel was opened with `tx_encoding` set to `proto3`.
+The `proto3json` encoding is not supported by this contract anymore.
+
+| **CosmosMsg** | `proto3` |
+|:------------------------------------------:|:--------:|
+| `Stargate` | ✅ |
+| `BankMsg::Send` | ✅ |
+| `BankMsg::Burn` | ❌ |
+| `IbcMsg::Transfer` | ✅ |
+| `IbcMsg::SendPacket` | N/A |
+| `IbcMsg::CloseChannel` | N/A |
+| `WasmMsg::*` | ✅ |
+| `GovMsg::*` | ✅ |
+| `StakingMsg::Delegate` | ✅ |
+| `StakingMsg::*` | 🟢 |
+| `DistributionMsg::WithdrawDelegatorReward` | 🟢 |
+| `DistributionMsg::*` | ✅ |
+
+Note that `🟢` means that the `CosmosMsg` is supported but not tested in the contract's test suite.
+These will be tested in the future.
+
+:::
+
+### `queries`
+
+This is a list of `QueryRequest`s that the contract will execute on the counterparty chain using the interchain account.
+
+:::warning
+
+This feature only works if the host (counterparty) chain is on ibc-go v7.5+. If the host chain is on an older version, then the packet will return an error acknowledgement.
+
+:::
+
+:::info
+
+If both `messages` and `queries` are provided, then the `messages` will be executed first. If the `messages` are successful, then the `queries` will be executed. If any of the `queries` fail, then the entire execution will fail.
+
+:::
+
+:::note
+
+In CosmosSDK, query execution is not generally deterministic. This is the main reason why not all query requests are supported. The supported query requests are:
+
+| **QueryRequest** | `proto3` |
+|:-------------------:|:--------:|
+| `BankQuery` | ✅ |
+| `Stargate` | ✅ |
+| `StakingQuery` | ✅ |
+| `IbcQuery` | ❌ |
+| `DistributionQuery` | ❌ |
+| `WasmQuery` | ❌ |
+
+Note that not all Stargate queries are supported. Only queries which are marked with [`module_query_safe`](https://github.com/cosmos/cosmos-sdk/blob/27a231ae4816fd8c3ee39a1cc02eccf977fb1b79/proto/cosmos/query/v1/query.proto#L36) tag are supported. You can find a list of supported queries in the [ibc-go documentation](https://ibc.cosmos.network/main/apps/interchain-accounts/messages/#queries) for different versions of ibc-go.
+
+Note that `WasmQuery` support will be added once [this issue](https://github.com/CosmWasm/wasmd/issues/1903) is resolved. Moreover, governance queries (as stargate queries) and `DistributionQuery` will be supported in the next version of the SDK.
+
+:::
+
+### `packet_memo`
+
+This is the IBC packet memo that will be included in the ICS-27 packet. It is optional and defaults to `""`.
+Additionally, the memo field is used by some IBC middleware to execute custom logic on the counterparty chain.
+But most of these middlewares do not yet support ICS-27 channels.
+
+### `timeout_seconds`
+
+This is the timeout in seconds that will be used for the ICS-27 packet. It is optional and defaults to [`DEFAULT_TIMEOUT_SECONDS`](https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/ibc/types/packet.rs#L15-L16).
+
+## `UpdateCallbackAddress`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/msg.rs#L92-L97
+```
+
+This message is used to update the contract address that this contract will send callbacks to.
+This is useful if the owner wants to change the contract that receives the callbacks.
+If set to `None`, then no callbacks will be sent.
+
+## `UpdateOwnership`
+
+```rust reference
+https://github.com/larry0x/cw-plus-plus/blob/ownable-v0.5.0/packages/ownable/derive/src/lib.rs#L86-L90
+```
+
+This message type is provided by the [cw-ownable](https://crates.io/crates/cw-ownable) crate. It wraps a
+`cw_ownable::Action` enum.
+
+```rust reference
+https://github.com/larry0x/cw-plus-plus/blob/ownable-v0.5.0/packages/ownable/src/lib.rs#L31-L57
+```
+
+The owner can propose to transfer the ownership of the contract to a new address using `Action::TransferOwnership` and
+set and expiry time for the proposal. If the proposal is accepted before the expiry time through
+`Action::AcceptOwnership`, then the ownership of the contract is transferred to the new address.
+
+You can learn more about `cw-ownable` in its crate documentation.
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/03-query-msg.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/03-query-msg.mdx
new file mode 100644
index 00000000..bd70c163
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/03-query-msg.mdx
@@ -0,0 +1,64 @@
+---
+title: QueryMsg
+sidebar_label: QueryMsg
+sidebar_position: 3
+slug: /contract-api/query-msg
+---
+
+# `QueryMsg`
+
+The `QueryMsg` is the message that allows you to see the state of the contract. Therefore, it is important to
+understand the state of the contract.
+
+## `GetChannel`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/msg.rs#L105-L107
+```
+
+This message is used to query the state of the ICS-27 channel as tracked by the contract. It returns
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/state.rs#L158-L166
+```
+
+## `GetContractState`
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.0/src/types/msg.rs#L108-L110
+```
+
+This message is used to query the state of the contract. It returns
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/state.rs#L39-L50
+```
+
+Lets look at the fields of the `ContractState`:
+
+### `ica_info`
+
+This field will be empty if the channel handshake has not been completed. Otherwise, it will contain the
+following information:
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/state.rs#L90-L96
+```
+
+### `callback_address`
+
+This is the contract address that the `cw-ica-controller` contract will send callbacks to. If this field is empty,
+then the contract will not send callbacks.
+
+## `Ownership`
+
+```rust reference
+https://github.com/larry0x/cw-plus-plus/blob/ownable-v0.5.0/packages/ownable/derive/src/lib.rs#L142-L144
+```
+
+This message type is provided by the [cw-ownable](https://crates.io/crates/cw-ownable) crate. It allows to query
+the ownership of the contract. It returns `Ownership`:
+
+```rust reference
+https://github.com/larry0x/cw-plus-plus/blob/ownable-v0.5.0/packages/ownable/src/lib.rs#L14-L29
+```
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/04-callbacks.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/04-callbacks.mdx
new file mode 100644
index 00000000..f503d925
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/04-callbacks.mdx
@@ -0,0 +1,138 @@
+---
+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.
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/05-events.mdx b/docs/versioned_docs/version-v0.6.x/contract-api/05-events.mdx
new file mode 100644
index 00000000..db248684
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/05-events.mdx
@@ -0,0 +1,40 @@
+---
+title: Events
+sidebar_label: Events
+sidebar_position: 5
+slug: /contract-api/events
+---
+
+# Events
+
+The `cw-ica-controller` contract emits events upon various channel and packet lifecycle events.
+I haven't really thought about what events should be emitted, so this is a work in progress and feel free to open
+an issue if you have any suggestions. Changes in events will not be considered breaking changes as they are not
+stored on the blockchain, thus, can be included in patch releases.
+
+Core IBC already emits events for channel and packet lifecycle events, so we keep the events to a minimum.
+
+The only events emitted by the contract are when an acknowledgement packet is received, so that an external
+indexer can index the result of the packet execution.
+
+## Attributes
+
+Whether or not the result of the packet execution was successful, the following attributes are emitted:
+
+| **Attribute Key** | **Attribute Value** |
+|:--------------------:|:-------------------:|
+| `packet_sequence` | String |
+| `packet_src_port` | String |
+| `packet_src_channel` | String |
+
+If the packet execution was successful, then the following attributes are also emitted:
+
+| **Attribute Key** | **Attribute Value** |
+|:-------------------:|:-------------------:|
+| `packet_ack_base64` | Base64 (String) |
+
+If the packet execution was unsuccessful, then the following attributes are also emitted:
+
+| **Attribute Key** | **Attribute Value** |
+|:-----------------:|:-------------------:|
+| `error` | String |
diff --git a/docs/versioned_docs/version-v0.6.x/contract-api/_category_.json b/docs/versioned_docs/version-v0.6.x/contract-api/_category_.json
new file mode 100644
index 00000000..efb2a00e
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/contract-api/_category_.json
@@ -0,0 +1,5 @@
+{
+ "label": "Contract API",
+ "position": 1,
+ "link": { "type": "doc", "id": "intro" }
+}
diff --git a/docs/versioned_docs/version-v0.6.x/how-it-works/01-introduction.mdx b/docs/versioned_docs/version-v0.6.x/how-it-works/01-introduction.mdx
new file mode 100644
index 00000000..4026ce3a
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/how-it-works/01-introduction.mdx
@@ -0,0 +1,38 @@
+---
+title: Introduction
+sidebar_label: Introduction
+sidebar_position: 1
+slug: /how-it-works/introduction
+---
+
+# How it works?
+
+:::info
+
+[ICS-27](https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts) is an interchain standard
+that specifies packet data structure, state machine handling logic, and encoding details for the account management
+system over an IBC channel between separate chains.
+
+:::
+
+CosmWasm provides native entry points for IBC channel and packet semantics (known as [ICS-4](https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics)).
+This allows CosmWasm contracts to implement interchain specifications for IBC applications. Some notable examples are:
+
+- [`cw20-ics20`](https://github.com/CosmWasm/cw-plus/tree/main/contracts/cw20-ics20) contract which implements the [ICS-20](https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer) fungible token transfer standard.
+- [`cw-ics721`](https://github.com/public-awesome/cw-ics721) contract which implements the [ICS-721](https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer) non-fungible token transfer standard.
+
+CosmWasm ICA Controller is a contract that implements the [ICS-27](https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts) interchain accounts standard. It allows this contract to manage accounts an another chain.
+This means that this contract doesn't rely on the golang implementation of the ICS-27, but rather implements it in Rust and provides a CosmWasm native API for managing accounts on another chain.
+
+It is important to note that this contract is not a full implementation of the ICS-27 standard. It only implements the
+controller contract, which is responsible for creating and managing accounts on another chain. The contract does not
+implement the ICA host module, which is responsible for executing the ICA transactions sent by the controller contract.
+
+Most IBC enabled chains do have the golang implementation of the ICS-27 standard, so you can use the CosmWasm ICA
+Controller contract to manage accounts on those chains, the Cosmos Hub, Osmosis, etc.
+
+In this section, we will go over the following topics:
+
+- ⚔️ [Golang ICA Controller vs CosmWasm ICA Controller](./02-go-vs-cosmwasm.mdx)
+- 🤝 [Channel Opening Handshake](./03-channel-handshake.mdx)
+- ✉️ [Packet Data Structure](./04-packet-data.mdx)
diff --git a/docs/versioned_docs/version-v0.6.x/how-it-works/02-go-vs-cosmwasm.mdx b/docs/versioned_docs/version-v0.6.x/how-it-works/02-go-vs-cosmwasm.mdx
new file mode 100644
index 00000000..844bf7a7
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/how-it-works/02-go-vs-cosmwasm.mdx
@@ -0,0 +1,48 @@
+---
+title: Go vs CosmWasm
+sidebar_label: Go vs CosmWasm
+sidebar_position: 2
+slug: /how-it-works/go-vs-cosmwasm
+---
+
+# Golang ICA Controller vs CosmWasm ICA Controller
+
+The golang implementation of the ICS-27 controller standard is also widely deployed on IBC enabled chains, with some
+notable exceptions being the Cosmos Hub and Osmosis.
+
+A contract developer could use the golang implementation of the ICA controller by submitting `CosmosMsg::Stargate`
+messages which would be handled by the golang implementation of the ICA controller.
+
+:::warning
+
+Using the golang implementation comes with a great disadvantage, which is that the golang implementation does not
+make callbacks to the contract that submitted the `CosmosMsg::Stargate` message! This means that the contract that
+submitted the `CosmosMsg::Stargate` message will not be able to know the result of the ICA transaction, nor the
+address of the newly created account on the other chain without intervention.
+
+:::
+
+:::tip
+
+Currently, Neutron and Nolus have custom bindings for the golang implementation of the ICA controller standard, which
+make callbacks to the contract that submitted the `CosmosMsg::Stargate` message. This means that you can use the
+golang implementation of the ICA controller standard on Neutron and Nolus without any problems. However, any
+applications that are built on these chains will not be able to be ported to other chains.
+
+:::
+
+`cw-ica-controller` solves this problem by making callbacks to a contract that the developer specifies.
+This means that the users of `cw-ica-controller` can use the same contract on any chain that supports CosmWasm.
+
+But there is more! `cw-ica-controller` is also able to do some things that the golang API limits you from doing.
+
+| **Feature** | `cw-ica-controller` | golang `ica-controller` | neutron bindings | **Description** |
+|:-------------------------------------------:|:-------------------:|:-----------------------:|:----------------:|:-------------------------------------------------------------------------------------------------------------------------:|
+| Callbacks | ✅ | ❌ | ✅ | Golang implementation does not make callbacks |
+| Submit `cosmwasm_std::CosmosMsg`s | ✅ | ❌ | ❌ | Golang implementation requires ICA transactions to be submitted in protobuf or `proto3json` format. |
+| Reopen an ICA channel with different params | ✅ | ❌ | ❌ | In golang implementation, if the channel closes due to timeout the channel can only be reopened with the same parameters. |
+| Change owner | ✅ | ❌ | ✅ | `cw-ica-controller` uses [`cw-ownable`][1] for owner management |
+| Live upgrades | ✅ | ❌ | ❌ | In golang implementation, new features require coordinated chain upgrades which could get blocked on upgrading CosmosSDK. |
+| Permanent channel closure | ✅ | ❌ | ❌ | Golang implementation allows any relayer to always reopen any ICA channel (with the same parameters). |
+
+[1]: https://github.com/larry0x/cw-plus-plus/tree/main/packages/ownable
diff --git a/docs/versioned_docs/version-v0.6.x/how-it-works/03-channel-handshake.mdx b/docs/versioned_docs/version-v0.6.x/how-it-works/03-channel-handshake.mdx
new file mode 100644
index 00000000..36dd4e5f
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/how-it-works/03-channel-handshake.mdx
@@ -0,0 +1,94 @@
+---
+title: Channel Opening Handshake
+sidebar_label: Channel Opening Handshake
+sidebar_position: 3
+slug: /how-it-works/channel-handshake
+---
+
+import HighlightTag from '@site/src/components/HighlightTag';
+
+# Channel Opening Handshake
+
+
+
+The channel opening handshake is a 4-step process (see [ICS-004](https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics#opening-handshake) to learn more):
+
+1. **Channel Open Init** (source chain)
+2. **Channel Open Try** (destination chain)
+3. **Channel Open Ack** (source chain)
+4. **Channel Open Confirm** (destination chain)
+
+Naturally, this contract only implements the first and third steps of the channel opening handshake, as the second and
+fourth steps are handled by the counterparty ICA host module.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/ibc/handshake.rs#L15-L46
+```
+
+## Channel Open Init
+
+### Authorization
+
+A channel open init message can be sent to any IBC module by any user, and it is up to the module to decide
+whether to accept the request or not.
+
+In the case of `cw-ica-controller`, only the contract itself can send a channel open init message. Since the sender of
+`MsgChannelOpenInit` is not passed to the contract (or any other IBC module), we enforce this by having a [state
+variable](https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/types/state.rs#L41) that keeps track of whether
+or not to accept channel open init messages. This variable is only set to true by the contract itself right before
+it is about to send a channel open init message in [`InstantiateMsg`](../contract-api/01-instantiate-msg.mdx) or
+[`ExecuteMsg::CreateChannel`](../contract-api/02-execute-msg.mdx#createchannel).
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/contract.rs#L130-L133
+```
+
+### Version Metadata and Ordering
+
+Whenever a new channel is created, the submitter of `MsgChannelOpenInit` must propose a version string and ordering.
+
+In IBC, the version string is used to determine whether or not the two modules on either side of the channel are
+compatible. The two modules are compatible if and only if they both support and agree on the same version string.
+Moreover, the version string may carry arbitrary metadata encoded in JSON format. This metadata can be used to
+carry key information about the channel, such as the encoding format, the application version, etc.
+
+The format of the version string for ICS-27 is specified [here](https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts#metadata-negotiation-summary).
+The following rust code shows the version metadata struct used to encode the version string:
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/ibc/types/metadata.rs#L19-L50
+```
+
+Since it is the contract itself that submits the `MsgChannelOpenInit`, the contract constructs the version string
+based on the `channel_open_init_options` that are passed to it in [`InstantiateMsg`](../contract-api/01-instantiate-msg.mdx) or [`ExecuteMsg::CreateChannel`](../contract-api/02-execute-msg.mdx#createchannel).
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/main/src/ibc/types/stargate.rs#L25-L57
+```
+
+The actual entry point for the `MsgChannelOpenInit` only does validation checks on channel parameters. For example,
+it checks that the channel is not already open.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/ibc/handshake.rs#L71-L126
+```
+
+## Channel Open Ack
+
+Unlike the `MsgChannelOpenInit`, the `MsgChannelOpenAck` is submitted by a relayer, and we do not need to worry about
+authorization. This step comes after the `MsgChannelOpenTry` is submitted by the counterparty ICA host module. In the
+`Try` step, the counterparty ICA host module may propose a different version string. Therefore, the contract must
+validate the version string and channel parameters once again in the `MsgChannelOpenAck`.
+
+:::note
+
+The interchain account address is passed to the contract in this step through the version string. In `Init` step,
+`cw-ica-controller` leaves the interchain account address empty, and the counterparty ICA host module fills it in.
+
+:::
+
+After validating the version string, the contract then stores the channel parameters in its state.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.4.2/src/ibc/handshake.rs#L128-L188
+```
diff --git a/docs/versioned_docs/version-v0.6.x/how-it-works/04-packet-data.mdx b/docs/versioned_docs/version-v0.6.x/how-it-works/04-packet-data.mdx
new file mode 100644
index 00000000..cdba47ed
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/how-it-works/04-packet-data.mdx
@@ -0,0 +1,49 @@
+---
+title: Packet Data
+sidebar_label: Packet Data
+sidebar_position: 4
+slug: /how-it-works/packet-data
+---
+
+import HighlightTag from '@site/src/components/HighlightTag';
+
+# Packet Data Structure
+
+
+
+The data that is sent over an IBC channel is called a packet. The packet data is defined by the IBC application module
+that is sending the packet. In the case of `cw-ica-controller`, the packet data is defined by the ICS-27 specification.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/ibc/types/packet.rs#L18-L44
+```
+
+The data field is encoded as protobuf bytes using the following function:
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/6843b80b29af97b9c4561ad487420e2f54857553/src/ibc/types/packet.rs#L90-L96
+```
+
+## From CosmosMsg to Packet Data
+
+Since this contract also provides an execute message to send `CosmosMsg`s as ICA packets, we have a helper function
+that converts a `CosmosMsg` to a packet data:
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/6843b80b29af97b9c4561ad487420e2f54857553/src/ibc/types/packet.rs#L98-L133
+```
+
+The specific conversion of each `CosmosMsg` variant into a protobuf any can be found in
+[`cosmos_msg.rs`](https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/types/cosmos_msg.rs).
+
+## Acknowledgement Data
+
+For each packet that is sent, the receiving module must respond with an acknowledgement packet. The acknowledgement
+packet is used to signal whether or not the ICA packet was successfully executed. The acknowledgement data is defined by the ICS-27 specification.
+
+```rust reference
+https://github.com/srdtrk/cw-ica-controller/blob/v0.5.0/src/ibc/types/packet.rs#L169-L177
+```
+
+`cw-ica-controller` includes the acknowledgement packet in the [callbacks](../contract-api/04-callbacks.mdx) that
+it makes to the external contract.
diff --git a/docs/versioned_docs/version-v0.6.x/how-it-works/_category_.json b/docs/versioned_docs/version-v0.6.x/how-it-works/_category_.json
new file mode 100644
index 00000000..b36fa485
--- /dev/null
+++ b/docs/versioned_docs/version-v0.6.x/how-it-works/_category_.json
@@ -0,0 +1,5 @@
+{
+ "label": "How it works?",
+ "position": 2,
+ "link": null
+}
diff --git a/docs/versioned_sidebars/version-v0.6.x-sidebars.json b/docs/versioned_sidebars/version-v0.6.x-sidebars.json
new file mode 100644
index 00000000..39332bfe
--- /dev/null
+++ b/docs/versioned_sidebars/version-v0.6.x-sidebars.json
@@ -0,0 +1,8 @@
+{
+ "docsSidebar": [
+ {
+ "type": "autogenerated",
+ "dirName": "."
+ }
+ ]
+}
diff --git a/docs/versions.json b/docs/versions.json
index 6a78cf57..6e389a6e 100644
--- a/docs/versions.json
+++ b/docs/versions.json
@@ -1,4 +1,5 @@
[
+ "v0.6.x",
"v0.5.x",
"v0.4.x"
]