Skip to content

Commit ba41a0b

Browse files
committed
Added IBCv2 chapters.
1 parent 89a5936 commit ba41a0b

File tree

5 files changed

+482
-0
lines changed

5 files changed

+482
-0
lines changed

docs/ibc2/_category_.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"label": "IBCv2",
3+
"position": 5
4+
}

docs/ibc2/entrypoints.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
title: Entrypoints
3+
sidebar_position: 2
4+
---
5+
6+
# Entrypoints in IBCv2
7+
8+
IBCv2 introduces four primary entry points for smart contracts interacting via the Inter-Blockchain
9+
Communication protocol. These entry points define how contracts handle incoming packets, timeouts,
10+
acknowledgements, and outbound messages. Each of these entry points plays a critical role in
11+
enabling robust, verifiable, and asynchronous cross-chain communication between smart contracts via IBCv2.
12+
13+
## Receive entrypoint
14+
15+
```rust
16+
#[cfg_attr(not(feature = "library"), entry_point)]
17+
pub fn ibc2_packet_receive(
18+
deps: DepsMut,
19+
env: Env,
20+
msg: Ibc2PacketReceiveMsg,
21+
) -> StdResult<IbcReceiveResponse> {
22+
// [...]
23+
Ok(IbcReceiveResponse::new(StdAck::success(b"\x01")))
24+
}
25+
```
26+
27+
The `ibc2_packet_receive` function is invoked when an IBCv2 packet is received on a port ID associated
28+
with the contract instance.
29+
30+
The **`Ibc2PacketReceiveMsg`** includes:
31+
32+
- the packet payload data,
33+
- the relayer address,
34+
- the source client ID,
35+
- the unique packet sequence number.
36+
37+
This entry point allows the contract to process incoming cross-chain messages.
38+
39+
There are two options for sending acknowledgements:
40+
41+
- Send a synchronous acknowledgement immediately using, for example, `IbcReceiveResponse::new(StdAck::success(b"\x01"))`.
42+
- Defer the acknowledgement for [asynchronous processing](message-passing#asynchronous-acknowledgements) using `IbcReceiveResponse::without_ack()`.
43+
44+
## Timeout entrypoint
45+
46+
```rust
47+
#[cfg_attr(not(feature = "library"), entry_point)]
48+
pub fn ibc2_packet_timeout(
49+
deps: DepsMut,
50+
env: Env,
51+
msg: Ibc2PacketTimeoutMsg,
52+
) -> StdResult<IbcBasicResponse> {
53+
// [...]
54+
Ok(IbcBasicResponse::default())
55+
}
56+
```
57+
58+
This function is triggered when a packet sent by the contract is proven not to have been received or
59+
processed by the destination chain. It serves as a fallback mechanism in case of connection issues.
60+
61+
The **`Ibc2PacketTimeoutMsg`** provides:
62+
63+
- the original packet payload,
64+
- source and destination client IDs,
65+
- the packet sequence number,
66+
- the relayer address.
67+
68+
## Acknowledgement entrypoint
69+
70+
```rust
71+
#[cfg_attr(not(feature = "library"), entry_point)]
72+
pub fn ibc2_acknowledge_receive(
73+
deps: DepsMut,
74+
env: Env,
75+
msg: Ibc2PacketAckMsg,
76+
) -> StdResult<IbcBasicResponse> {
77+
// [...]
78+
Ok(IbcBasicResponse::default())
79+
}
80+
```
81+
82+
When an acknowledgement for a previously sent packet is received, this entry point is called.
83+
84+
The **`Ibc2PacketAckMsg`** contains:
85+
86+
- source and destination client IDs,
87+
- the relayer address,
88+
- the acknowledgement response data,
89+
- the payload of the original packet.
90+
91+
This allows the contract to confirm and act upon the acknowledgement of a sent message.
92+
93+
## Send entrypoint
94+
95+
```rust
96+
#[cfg_attr(not(feature = "library"), entry_point)]
97+
pub fn ibc2_packet_send(
98+
deps: DepsMut,
99+
env: Env,
100+
msg: Ibc2PacketSendMsg,
101+
) -> StdResult<IbcBasicResponse> {
102+
// [...]
103+
Ok(IbcBasicResponse::default())
104+
}
105+
```
106+
107+
To support permissionless packet sending, IBCv2 introduces the `ibc2_packet_send` entry point.
108+
This function allows the contract to validate outbound messages initiated from its associated port.
109+
110+
The **`Ibc2PacketSendMsg`** includes:
111+
112+
- source and destination client IDs,
113+
- packet sequence number,
114+
- signer address,
115+
- message payload.

docs/ibc2/example.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
title: Example contract
3+
sidebar_position: 4
4+
---
5+
6+
# Ping-Pong contract
7+
8+
This CosmWasm smart contract implements a basic IBCv2 Ping-Pong protocol using custom IBCv2
9+
messages. It demonstrates cross-chain communication by sending a `PingPongMsg` back and forth
10+
between two contracts across IBCv2-compatible clients.
11+
12+
The core idea is to initialize a connection with a "ping" (starting with counter = 1) and increment
13+
the counter with each received response, sending it back to the origin. The contract handles packet
14+
receipt, acknowledgement, timeouts, and enforces security checks on packet sends.
15+
16+
```rust
17+
use cosmwasm_schema::cw_serde;
18+
use cosmwasm_std::{
19+
entry_point, from_json, to_json_vec, Binary, ContractInfoResponse, DepsMut, Empty, Env,
20+
Ibc2Msg, Ibc2PacketAckMsg, Ibc2PacketReceiveMsg, Ibc2PacketSendMsg, Ibc2PacketTimeoutMsg,
21+
Ibc2Payload, IbcBasicResponse, IbcReceiveResponse, MessageInfo, Response, StdAck, StdError,
22+
StdResult,
23+
};
24+
25+
/// Represents a simple IBCv2 ping-pong message containing a counter.
26+
#[cw_serde]
27+
pub struct PingPongMsg {
28+
pub counter: u64,
29+
}
30+
31+
/// Initialization message for the contract.
32+
#[cw_serde]
33+
pub struct ExecuteMsg {
34+
pub source_client: String,
35+
pub destination_port: String,
36+
}
37+
38+
/// Initializes the contract.
39+
///
40+
/// # Arguments
41+
/// - `_deps`: Mutable dependencies of the contract.
42+
/// - `_env`: The current blockchain environment.
43+
/// - `_info`: Message sender information (unused).
44+
/// - `_msg`: Empty message.
45+
///
46+
#[cfg_attr(not(feature = "library"), entry_point)]
47+
pub fn instantiate(
48+
_deps: DepsMut,
49+
_env: Env,
50+
_info: MessageInfo,
51+
_msg: Empty,
52+
) -> StdResult<Response> {
53+
Ok(Response::default())
54+
}
55+
56+
/// Sends the first IBCv2 ping message.
57+
///
58+
/// # Arguments
59+
/// - `deps`: Mutable dependencies of the contract.
60+
/// - `env`: The current blockchain environment.
61+
/// - `_info`: Message sender information (unused).
62+
/// - `msg`: The execute message containing client and port info.
63+
///
64+
/// # Returns
65+
/// - `StdResult<Response>`: Result containing a response with the IBCv2 packet to be sent.
66+
#[cfg_attr(not(feature = "library"), entry_point)]
67+
pub fn execute(
68+
deps: DepsMut,
69+
env: Env,
70+
_info: MessageInfo,
71+
msg: ExecuteMsg,
72+
) -> StdResult<Response> {
73+
let ContractInfoResponse { ibc2_port, .. } = deps
74+
.querier
75+
.query_wasm_contract_info(env.contract.address)?;
76+
let source_port =
77+
ibc2_port.ok_or(StdError::generic_err("Contract's IBCv2 port ID not found"))?;
78+
let new_payload = Ibc2Payload::new(
79+
source_port,
80+
msg.destination_port,
81+
"V1".to_owned(),
82+
"application/json".to_owned(),
83+
Binary::new(to_json_vec(&PingPongMsg { counter: 1 })?),
84+
);
85+
86+
let new_msg = Ibc2Msg::SendPacket {
87+
source_client: msg.source_client,
88+
payloads: vec![new_payload],
89+
timeout: env.block.time.plus_minutes(5_u64),
90+
};
91+
92+
Ok(Response::default().add_message(new_msg))
93+
}
94+
95+
/// Handles acknowledgements for IBCv2 packets. No action is taken in this implementation.
96+
///
97+
/// # Arguments
98+
/// - `_deps`: Mutable dependencies of the contract.
99+
/// - `_env`: The current blockchain environment.
100+
/// - `_msg`: Acknowledgement message received from the IBC channel.
101+
///
102+
/// # Returns
103+
/// - `StdResult<IbcBasicResponse>`: Default empty response.
104+
#[cfg_attr(not(feature = "library"), entry_point)]
105+
pub fn ibc2_packet_ack(
106+
_deps: DepsMut,
107+
_env: Env,
108+
_msg: Ibc2PacketAckMsg,
109+
) -> StdResult<IbcBasicResponse> {
110+
// Do nothing
111+
112+
Ok(IbcBasicResponse::default())
113+
}
114+
115+
/// Handles the receipt of an IBCv2 packet and responds by incrementing the counter
116+
/// and sending it back to the source.
117+
///
118+
/// # Arguments
119+
/// - `_deps`: Mutable dependencies of the contract.
120+
/// - `env`: The current blockchain environment.
121+
/// - `msg`: The received IBCv2 packet message.
122+
///
123+
/// # Returns
124+
/// - `StdResult<IbcReceiveResponse>`: Response including a new IBC packet and a successful ack.
125+
#[cfg_attr(not(feature = "library"), entry_point)]
126+
pub fn ibc2_packet_receive(
127+
_deps: DepsMut,
128+
env: Env,
129+
msg: Ibc2PacketReceiveMsg,
130+
) -> StdResult<IbcReceiveResponse> {
131+
let binary_payload = &msg.payload.value;
132+
let json_payload: PingPongMsg = from_json(binary_payload)?;
133+
134+
let new_payload = Ibc2Payload::new(
135+
// Swap the source with destination ports to send the message back to the source contract
136+
msg.payload.destination_port,
137+
msg.payload.source_port,
138+
msg.payload.version,
139+
msg.payload.encoding,
140+
Binary::new(to_json_vec(&PingPongMsg {
141+
counter: json_payload.counter + 1,
142+
})?),
143+
);
144+
145+
let new_msg = Ibc2Msg::SendPacket {
146+
source_client: msg.source_client,
147+
payloads: vec![new_payload],
148+
timeout: env.block.time.plus_minutes(5_u64),
149+
};
150+
151+
Ok(IbcReceiveResponse::new(StdAck::success(b"\x01")).add_message(new_msg))
152+
}
153+
154+
/// Handles timeouts of previously sent IBC packets. Automatically resends the message
155+
/// without validation or retry limits.
156+
///
157+
/// # Arguments
158+
/// - `_deps`: Mutable dependencies of the contract.
159+
/// - `env`: The current blockchain environment.
160+
/// - `msg`: The timeout message with the failed payload.
161+
///
162+
/// # Returns
163+
/// - `StdResult<IbcBasicResponse>`: Response with the resend attempt.
164+
#[cfg_attr(not(feature = "library"), entry_point)]
165+
pub fn ibc2_packet_timeout(
166+
_deps: DepsMut,
167+
env: Env,
168+
msg: Ibc2PacketTimeoutMsg,
169+
) -> StdResult<IbcBasicResponse> {
170+
// Let's resend the message without any check.
171+
// It'd be good to constrain the number of trials.
172+
173+
let msg = Ibc2Msg::SendPacket {
174+
source_client: msg.source_client,
175+
payloads: vec![msg.payload],
176+
timeout: env.block.time.plus_minutes(5_u64),
177+
};
178+
179+
Ok(IbcBasicResponse::default().add_message(msg))
180+
}
181+
182+
/// Called when an IBCv2 packet is sent. Validates that the sender is the contract itself.
183+
///
184+
/// # Arguments
185+
/// - `_deps`: Mutable dependencies of the contract.
186+
/// - `_env`: The current blockchain environment.
187+
/// - `msg`: The packet send message.
188+
///
189+
/// # Returns
190+
/// - `StdResult<IbcBasicResponse>`: Default response if sender is valid, error otherwise.
191+
#[cfg_attr(not(feature = "library"), entry_point)]
192+
pub fn ibc2_packet_send(
193+
_deps: DepsMut,
194+
_env: Env,
195+
msg: Ibc2PacketSendMsg,
196+
) -> StdResult<IbcBasicResponse> {
197+
if msg.signer != _env.contract.address {
198+
return Err(StdError::generic_err(
199+
"Only this contract can send messages from its IBCv2 port ID",
200+
));
201+
}
202+
Ok(IbcBasicResponse::default())
203+
}
204+
```

docs/ibc2/getting-started.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
# Getting started
6+
7+
The CosmWasm module leverages the [ibc-go](https://ibc.cosmos.network/main/) implementation to
8+
enable interaction with other blockchains through the Inter-Blockchain Communication (IBC) protocol.
9+
With the release of ibc-go version 10,
10+
a new protocol version - [IBCv2](https://ibcprotocol.dev/blog/ibc-v2-announcement) - was introduced.
11+
IBCv2 expands the interoperability of the Cosmos ecosystem to include non-Cosmos blockchains.
12+
To support this broader scope, the protocol team simplified the communication model and reduced
13+
the number of required entry points. This streamlining makes it more practical to implement IBC
14+
support on chains such as Ethereum. As a result, smart contract developers now need to implement
15+
only a few well-defined entry points to fully harness cross-chain capabilities.
16+
17+
:::info
18+
19+
To use IBCv2 entry points and messages in your smart contract, ensure that the `ibc2` feature is
20+
enabled in your `cosmwasm-std` dependency. Add the following to your `Cargo.toml`:
21+
22+
```toml
23+
cosmwasm-std = { version = "3.0", features = ["ibc2"] }
24+
```
25+
26+
:::
27+
28+
:::tip
29+
30+
This section of the documentation provides a basic overview of how to configure smart contracts
31+
to use IBCv2 entry points and communicate with services and contracts on other chains.
32+
For a deeper understanding of the IBC architecture,
33+
refer to the [official ibc-go documentation](https://ibc.cosmos.network/main/).
34+
35+
:::

0 commit comments

Comments
 (0)