cosmwasm_std/query/
wasm.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::{Binary, HexBinary};
5
6use super::query_response::QueryResponseType;
7
8#[non_exhaustive]
9#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
10#[serde(rename_all = "snake_case")]
11pub enum WasmQuery {
12    /// this queries the public API of another contract at a known address (with known ABI)
13    /// Return value is whatever the contract returns (caller should know), wrapped in a
14    /// ContractResult that is JSON encoded.
15    Smart {
16        contract_addr: String,
17        /// msg is the json-encoded QueryMsg struct
18        msg: Binary,
19    },
20    /// this queries the raw kv-store of the contract.
21    /// returns the raw, unparsed data stored at that key, which may be an empty vector if not present
22    Raw {
23        contract_addr: String,
24        /// Key is the raw key used in the contracts Storage
25        key: Binary,
26    },
27    /// Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime
28    ContractInfo { contract_addr: String },
29    /// Returns a [`CodeInfoResponse`] with metadata of the code
30    #[cfg(feature = "cosmwasm_1_2")]
31    CodeInfo { code_id: u64 },
32}
33
34#[non_exhaustive]
35#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)]
36pub struct ContractInfoResponse {
37    pub code_id: u64,
38    /// address that instantiated this contract
39    pub creator: String,
40    /// admin who can run migrations (if any)
41    pub admin: Option<String>,
42    /// if set, the contract is pinned to the cache, and thus uses less gas when called
43    pub pinned: bool,
44    /// set if this contract has bound an IBC port
45    pub ibc_port: Option<String>,
46}
47
48impl QueryResponseType for ContractInfoResponse {}
49
50impl ContractInfoResponse {
51    /// Constructor for testing frameworks such as cw-multi-test.
52    /// This is required because query response types should be #[non_exhaustive].
53    /// As a contract developer you should not need this constructor since
54    /// query responses are constructed for you via deserialization.
55    #[doc(hidden)]
56    #[deprecated(
57        note = "Use ContractInfoResponse::default() and mutate the fields you want to set."
58    )]
59    pub fn new(code_id: u64, creator: impl Into<String>) -> Self {
60        ContractInfoResponse {
61            code_id,
62            creator: creator.into(),
63            ..Default::default()
64        }
65    }
66}
67
68/// The essential data from wasmd's [CodeInfo]/[CodeInfoResponse].
69///
70/// `code_hash`/`data_hash` was renamed to `checksum` to follow the CosmWasm
71/// convention and naming in `instantiate2_address`.
72///
73/// [CodeInfo]: https://github.com/CosmWasm/wasmd/blob/v0.30.0/proto/cosmwasm/wasm/v1/types.proto#L62-L72
74/// [CodeInfoResponse]: https://github.com/CosmWasm/wasmd/blob/v0.30.0/proto/cosmwasm/wasm/v1/query.proto#L184-L199
75#[non_exhaustive]
76#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)]
77pub struct CodeInfoResponse {
78    pub code_id: u64,
79    /// The address that initially stored the code
80    pub creator: String,
81    /// The hash of the Wasm blob
82    pub checksum: HexBinary,
83}
84
85impl_response_constructor!(
86    CodeInfoResponse,
87    code_id: u64,
88    creator: String,
89    checksum: HexBinary
90);
91
92impl QueryResponseType for CodeInfoResponse {}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97    use crate::to_json_binary;
98
99    #[test]
100    fn wasm_query_contract_info_serialization() {
101        let query = WasmQuery::ContractInfo {
102            contract_addr: "aabbccdd456".into(),
103        };
104        let json = to_json_binary(&query).unwrap();
105        assert_eq!(
106            String::from_utf8_lossy(&json),
107            r#"{"contract_info":{"contract_addr":"aabbccdd456"}}"#,
108        );
109    }
110
111    #[test]
112    #[cfg(feature = "cosmwasm_1_2")]
113    fn wasm_query_code_info_serialization() {
114        let query = WasmQuery::CodeInfo { code_id: 70 };
115        let json = to_json_binary(&query).unwrap();
116        assert_eq!(
117            String::from_utf8_lossy(&json),
118            r#"{"code_info":{"code_id":70}}"#,
119        );
120    }
121
122    #[test]
123    fn contract_info_response_serialization() {
124        let response = ContractInfoResponse {
125            code_id: 67,
126            creator: "jane".to_string(),
127            admin: Some("king".to_string()),
128            pinned: true,
129            ibc_port: Some("wasm.123".to_string()),
130        };
131        let json = to_json_binary(&response).unwrap();
132        assert_eq!(
133            String::from_utf8_lossy(&json),
134            r#"{"code_id":67,"creator":"jane","admin":"king","pinned":true,"ibc_port":"wasm.123"}"#,
135        );
136    }
137
138    #[test]
139    #[cfg(feature = "cosmwasm_1_2")]
140    fn code_info_response_serialization() {
141        use crate::HexBinary;
142
143        let response = CodeInfoResponse {
144            code_id: 67,
145            creator: "jane".to_string(),
146            checksum: HexBinary::from_hex(
147                "f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00",
148            )
149            .unwrap(),
150        };
151        let json = to_json_binary(&response).unwrap();
152        assert_eq!(
153            String::from_utf8_lossy(&json),
154            r#"{"code_id":67,"creator":"jane","checksum":"f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00"}"#,
155        );
156    }
157}