layer_climb_core/signing/ibc/
tx.rs

1use crate::{
2    events::IbcPacket,
3    ibc_types::{
4        IbcChannelId, IbcChannelOrdering, IbcChannelVersion, IbcClientId, IbcConnectionId,
5        IbcPortId,
6    },
7    prelude::*,
8};
9
10// hermes connection handshake: https://github.com/informalsystems/hermes/blob/ccd1d907df4853203349057bba200077254bb83d/crates/relayer/src/connection.rs#L566
11// ibc-go connection handshake:
12impl SigningClient {
13    // this is used for creating a cross-chain client
14    // so we need the other chain's client and consensus state
15    pub async fn ibc_create_client(
16        &self,
17        remote_querier: &QueryClient,
18        trusting_period_secs: Option<u64>,
19        tx_builder: Option<TxBuilder<'_>>,
20    ) -> Result<layer_climb_proto::abci::TxResponse> {
21        let msg = self
22            .ibc_create_client_msg(trusting_period_secs, remote_querier)
23            .await?;
24
25        tx_builder
26            .unwrap_or_else(|| self.tx_builder())
27            .broadcast([proto_into_any(&msg)?])
28            .await
29    }
30
31    pub async fn ibc_update_client(
32        &self,
33        client_id: &IbcClientId,
34        remote_querier: &QueryClient,
35        trusted_height: Option<layer_climb_proto::RevisionHeight>,
36        tx_builder: Option<TxBuilder<'_>>,
37    ) -> Result<layer_climb_proto::abci::TxResponse> {
38        let msg = proto_into_any(
39            &self
40                .ibc_update_client_msg(client_id, remote_querier, trusted_height)
41                .await?,
42        )?;
43
44        tx_builder
45            .unwrap_or_else(|| self.tx_builder())
46            .broadcast([msg])
47            .await
48    }
49
50    pub async fn ibc_open_connection_init(
51        &self,
52        client_id: &IbcClientId,
53        counterparty_client_id: &IbcClientId,
54        tx_builder: Option<TxBuilder<'_>>,
55    ) -> Result<layer_climb_proto::abci::TxResponse> {
56        let msg = proto_into_any(
57            &self
58                .ibc_open_connection_init_msg(client_id, counterparty_client_id)
59                .await?,
60        )?;
61
62        let resp = tx_builder
63            .unwrap_or_else(|| self.tx_builder())
64            .broadcast([msg])
65            .await;
66
67        // wait 1 block so client update height - 1 will see it
68        self.querier.wait_blocks(1, None).await?;
69
70        resp
71    }
72
73    pub async fn ibc_open_connection_try(
74        &self,
75        client_id: &IbcClientId,
76        counterparty_client_id: &IbcClientId,
77        counterparty_connection_id: &IbcConnectionId,
78        remote_querier: &QueryClient,
79        tx_builder: Option<TxBuilder<'_>>,
80    ) -> Result<layer_climb_proto::abci::TxResponse> {
81        let msg = self
82            .ibc_open_connection_try_msg(
83                client_id,
84                counterparty_client_id,
85                counterparty_connection_id,
86                remote_querier,
87            )
88            .await?;
89
90        let resp = tx_builder
91            .unwrap_or_else(|| self.tx_builder())
92            .broadcast([proto_into_any(&msg)?])
93            .await;
94
95        // wait 1 block so client update height - 1 will see it
96        self.querier.wait_blocks(1, None).await?;
97
98        resp
99    }
100
101    pub async fn ibc_open_connection_ack(
102        &self,
103        client_id: &IbcClientId,
104        counterparty_client_id: &IbcClientId,
105        connection_id: &IbcConnectionId,
106        counterparty_connection_id: &IbcConnectionId,
107        remote_querier: &QueryClient,
108        tx_builder: Option<TxBuilder<'_>>,
109    ) -> Result<layer_climb_proto::abci::TxResponse> {
110        let msg = self
111            .ibc_open_connection_ack_msg(
112                client_id,
113                counterparty_client_id,
114                connection_id,
115                counterparty_connection_id,
116                remote_querier,
117            )
118            .await?;
119
120        let resp = tx_builder
121            .unwrap_or_else(|| self.tx_builder())
122            .broadcast([proto_into_any(&msg)?])
123            .await;
124
125        // wait 1 block so client update height - 1 will see it
126        self.querier.wait_blocks(1, None).await?;
127
128        resp
129    }
130
131    pub async fn ibc_open_connection_confirm(
132        &self,
133        client_id: &IbcClientId,
134        counterparty_client_id: &IbcClientId,
135        connection_id: &IbcConnectionId,
136        counterparty_connection_id: &IbcConnectionId,
137        remote_querier: &QueryClient,
138        tx_builder: Option<TxBuilder<'_>>,
139    ) -> Result<layer_climb_proto::abci::TxResponse> {
140        let msg = self
141            .ibc_open_connection_confirm_msg(
142                client_id,
143                counterparty_client_id,
144                connection_id,
145                counterparty_connection_id,
146                remote_querier,
147            )
148            .await?;
149
150        tx_builder
151            .unwrap_or_else(|| self.tx_builder())
152            .broadcast([proto_into_any(&msg)?])
153            .await
154    }
155
156    pub async fn ibc_open_channel_init(
157        &self,
158        connection_id: &IbcConnectionId,
159        port_id: &IbcPortId,
160        version: &IbcChannelVersion,
161        ordering: IbcChannelOrdering,
162        counterparty_port_id: &IbcPortId,
163        tx_builder: Option<TxBuilder<'_>>,
164    ) -> Result<layer_climb_proto::abci::TxResponse> {
165        let msg = self.ibc_open_channel_init_msg(
166            connection_id,
167            port_id,
168            version,
169            ordering,
170            counterparty_port_id,
171        )?;
172
173        let resp = tx_builder
174            .unwrap_or_else(|| self.tx_builder())
175            .broadcast([proto_into_any(&msg)?])
176            .await;
177
178        // wait 1 block so client update height - 1 will see it
179        self.querier.wait_blocks(1, None).await?;
180
181        resp
182    }
183
184    #[allow(clippy::too_many_arguments)]
185    pub async fn ibc_open_channel_try(
186        &self,
187        client_id: &IbcClientId,
188        connection_id: &IbcConnectionId,
189        port_id: &IbcPortId,
190        version: &IbcChannelVersion,
191        counterparty_port_id: &IbcPortId,
192        counterparty_channel_id: &IbcChannelId,
193        counterparty_version: &IbcChannelVersion,
194        ordering: IbcChannelOrdering,
195        remote_querier: &QueryClient,
196        tx_builder: Option<TxBuilder<'_>>,
197    ) -> Result<layer_climb_proto::abci::TxResponse> {
198        let msg = self
199            .ibc_open_channel_try_msg(
200                client_id,
201                connection_id,
202                port_id,
203                version,
204                counterparty_port_id,
205                counterparty_channel_id,
206                counterparty_version,
207                ordering,
208                remote_querier,
209            )
210            .await?;
211
212        let resp = tx_builder
213            .unwrap_or_else(|| self.tx_builder())
214            .broadcast([proto_into_any(&msg)?])
215            .await;
216
217        // wait 1 block so client update height - 1 will see it
218        self.querier.wait_blocks(1, None).await?;
219
220        resp
221    }
222
223    #[allow(clippy::too_many_arguments)]
224    pub async fn ibc_open_channel_ack(
225        &self,
226        client_id: &IbcClientId,
227        channel_id: &IbcChannelId,
228        port_id: &IbcPortId,
229        counterparty_port_id: &IbcPortId,
230        counterparty_channel_id: &IbcChannelId,
231        counterparty_version: &IbcChannelVersion,
232        remote_querier: &QueryClient,
233        tx_builder: Option<TxBuilder<'_>>,
234    ) -> Result<layer_climb_proto::abci::TxResponse> {
235        let msg = self
236            .ibc_open_channel_ack_msg(
237                client_id,
238                channel_id,
239                port_id,
240                counterparty_port_id,
241                counterparty_channel_id,
242                counterparty_version,
243                remote_querier,
244            )
245            .await?;
246
247        let resp = tx_builder
248            .unwrap_or_else(|| self.tx_builder())
249            .broadcast([proto_into_any(&msg)?])
250            .await;
251
252        // wait 1 block so client update height - 1 will see it
253        self.querier.wait_blocks(1, None).await?;
254
255        resp
256    }
257
258    #[allow(clippy::too_many_arguments)]
259    pub async fn ibc_open_channel_confirm(
260        &self,
261        client_id: &IbcClientId,
262        channel_id: &IbcChannelId,
263        port_id: &IbcPortId,
264        counterparty_port_id: &IbcPortId,
265        counterparty_channel_id: &IbcChannelId,
266        remote_querier: &QueryClient,
267        tx_builder: Option<TxBuilder<'_>>,
268    ) -> Result<layer_climb_proto::abci::TxResponse> {
269        let msg = self
270            .ibc_open_channel_confirm_msg(
271                client_id,
272                channel_id,
273                port_id,
274                counterparty_port_id,
275                counterparty_channel_id,
276                remote_querier,
277            )
278            .await?;
279
280        tx_builder
281            .unwrap_or_else(|| self.tx_builder())
282            .broadcast([proto_into_any(&msg)?])
283            .await
284    }
285
286    // the querier is where the packet arrived *from*
287    // this should be called on the chain the packet is being sent *to*
288    pub async fn ibc_packet_recv(
289        &self,
290        client_id: &IbcClientId,
291        packet: IbcPacket,
292        remote_querier: &QueryClient,
293        tx_builder: Option<TxBuilder<'_>>,
294    ) -> Result<layer_climb_proto::abci::TxResponse> {
295        let msg = self
296            .ibc_packet_recv_msg(client_id, packet, remote_querier)
297            .await?;
298
299        tx_builder
300            .unwrap_or_else(|| self.tx_builder())
301            .broadcast([proto_into_any(&msg)?])
302            .await
303    }
304
305    // the querier is where the packet arrived *from*
306    // this should be called on the chain the packet is being sent *to*
307    pub async fn ibc_packet_ack(
308        &self,
309        client_id: &IbcClientId,
310        packet: IbcPacket,
311        remote_querier: &QueryClient,
312        tx_builder: Option<TxBuilder<'_>>,
313    ) -> Result<layer_climb_proto::abci::TxResponse> {
314        let msg = self
315            .ibc_packet_ack_msg(client_id, packet, remote_querier)
316            .await?;
317
318        tx_builder
319            .unwrap_or_else(|| self.tx_builder())
320            .broadcast([proto_into_any(&msg)?])
321            .await
322    }
323}