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    pub async fn contract_execute(
71        &self,
72        address: &Address,
73        msg: &impl Serialize,
74        funds: Vec<layer_climb_proto::Coin>,
75        tx_builder: Option<TxBuilder<'_>>,
76    ) -> Result<layer_climb_proto::abci::TxResponse> {
77        tx_builder
78            .unwrap_or_else(|| self.tx_builder())
79            .broadcast([proto_into_any(
80                &self.contract_execute_msg(address, funds, msg)?,
81            )?])
82            .await
83    }
84
85    pub async fn contract_migrate(
86        &self,
87        address: &Address,
88        code_id: u64,
89        msg: &impl Serialize,
90        tx_builder: Option<TxBuilder<'_>>,
91    ) -> Result<layer_climb_proto::abci::TxResponse> {
92        tx_builder
93            .unwrap_or_else(|| self.tx_builder())
94            .broadcast([proto_into_any(
95                &self.contract_migrate_msg(address, code_id, msg)?,
96            )?])
97            .await
98    }
99}