Skip to main content

layer_climb_core/signing/contract/
tx.rs

1use serde::Serialize;
2
3use crate::{
4    events::{
5        EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V1, EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V2,
6        EVENT_ATTR_STORE_CODE_ID, EVENT_TYPE_CONTRACT_INSTANTIATE, EVENT_TYPE_CONTRACT_STORE_CODE,
7    },
8    prelude::*,
9};
10
11impl SigningClient {
12    // returns the code id
13    pub async fn contract_upload_file(
14        &self,
15        wasm_byte_code: Vec<u8>,
16        tx_builder: Option<TxBuilder<'_>>,
17    ) -> Result<(u64, layer_climb_proto::abci::TxResponse)> {
18        let resp = tx_builder
19            .unwrap_or_else(|| self.tx_builder())
20            .broadcast([proto_into_any(
21                &self.contract_upload_file_msg(wasm_byte_code)?,
22            )?])
23            .await?;
24
25        let code_id: u64 = CosmosTxEvents::from(&resp)
26            .attr_first(EVENT_TYPE_CONTRACT_STORE_CODE, EVENT_ATTR_STORE_CODE_ID)?
27            .value()
28            .parse()?;
29
30        Ok((code_id, resp))
31    }
32
33    pub async fn contract_instantiate(
34        &self,
35        admin: impl Into<Option<Address>>,
36        code_id: u64,
37        label: impl ToString,
38        msg: &impl Serialize,
39        funds: Vec<layer_climb_proto::Coin>,
40        tx_builder: Option<TxBuilder<'_>>,
41    ) -> Result<(Address, layer_climb_proto::abci::TxResponse)> {
42        let resp = tx_builder
43            .unwrap_or_else(|| self.tx_builder())
44            .broadcast([proto_into_any(
45                &self.contract_instantiate_msg(admin, code_id, label, funds, msg)?,
46            )?])
47            .await?;
48
49        let events = CosmosTxEvents::from(&resp);
50
51        let contract_address = events
52            .attr_first(
53                EVENT_TYPE_CONTRACT_INSTANTIATE,
54                EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V1,
55            )
56            .or_else(|_| {
57                events.attr_first(
58                    EVENT_TYPE_CONTRACT_INSTANTIATE,
59                    EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V2,
60                )
61            })?
62            .value()
63            .to_string();
64
65        let contract_address = self.querier.chain_config.parse_address(&contract_address)?;
66
67        Ok((contract_address, resp))
68    }
69
70    #[allow(clippy::too_many_arguments)]
71    pub async fn contract_instantiate2(
72        &self,
73        admin: impl Into<Option<Address>>,
74        code_id: u64,
75        label: impl ToString,
76        msg: &impl Serialize,
77        funds: Vec<layer_climb_proto::Coin>,
78        salt: Vec<u8>,
79        fix_msg: bool,
80        tx_builder: Option<TxBuilder<'_>>,
81    ) -> Result<(Address, layer_climb_proto::abci::TxResponse)> {
82        let resp = tx_builder
83            .unwrap_or_else(|| self.tx_builder())
84            .broadcast([proto_into_any(&self.contract_instantiate2_msg(
85                admin, code_id, label, funds, salt, fix_msg, msg,
86            )?)?])
87            .await?;
88
89        let events = CosmosTxEvents::from(&resp);
90
91        let contract_address = events
92            .attr_first(
93                EVENT_TYPE_CONTRACT_INSTANTIATE,
94                EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V1,
95            )
96            .or_else(|_| {
97                events.attr_first(
98                    EVENT_TYPE_CONTRACT_INSTANTIATE,
99                    EVENT_ATTR_INSTANTIATE_CONTRACT_ADDRESS_V2,
100                )
101            })?
102            .value()
103            .to_string();
104
105        let contract_address = self.querier.chain_config.parse_address(&contract_address)?;
106
107        Ok((contract_address, resp))
108    }
109
110    pub async fn contract_execute(
111        &self,
112        address: &Address,
113        msg: &impl Serialize,
114        funds: Vec<layer_climb_proto::Coin>,
115        tx_builder: Option<TxBuilder<'_>>,
116    ) -> Result<layer_climb_proto::abci::TxResponse> {
117        tx_builder
118            .unwrap_or_else(|| self.tx_builder())
119            .broadcast([proto_into_any(
120                &self.contract_execute_msg(address, funds, msg)?,
121            )?])
122            .await
123    }
124
125    pub async fn contract_migrate(
126        &self,
127        address: &Address,
128        code_id: u64,
129        msg: &impl Serialize,
130        tx_builder: Option<TxBuilder<'_>>,
131    ) -> Result<layer_climb_proto::abci::TxResponse> {
132        tx_builder
133            .unwrap_or_else(|| self.tx_builder())
134            .broadcast([proto_into_any(
135                &self.contract_migrate_msg(address, code_id, msg)?,
136            )?])
137            .await
138    }
139}