neutron_sdk/interchain_queries/
types.rs

1use crate::{
2    bindings::types::{KVKey, StorageValue},
3    errors::error::NeutronResult,
4};
5use cosmwasm_std::{from_json, StdError, Uint128};
6use schemars::{JsonSchema, _serde_json::Value};
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9pub const QUERY_TYPE_KV_VALUE: &str = "kv";
10pub const QUERY_TYPE_TX_VALUE: &str = "tx";
11
12/// Maximum length of address
13pub const MAX_ADDR_LEN: usize = 255;
14
15#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
16pub enum TransactionFilterOp {
17    Eq,
18    Lt,
19    Gt,
20    Lte,
21    Gte,
22}
23
24#[derive(PartialEq, Eq, Debug)]
25pub enum TransactionFilterValue {
26    String(String),
27    Int(u64),
28}
29
30impl<'de> Deserialize<'de> for TransactionFilterValue {
31    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
32    where
33        D: Deserializer<'de>,
34    {
35        use serde::de::Error;
36
37        let v = Value::deserialize(deserializer)?;
38        let n = v.as_u64();
39        if let Some(n) = n {
40            Ok(Self::Int(n))
41        } else {
42            let n = v
43                .as_str()
44                .ok_or_else(|| D::Error::custom("Value must be number or string"))?;
45            Ok(Self::String(n.to_string()))
46        }
47    }
48}
49
50impl Serialize for TransactionFilterValue {
51    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52    where
53        S: Serializer,
54    {
55        match self {
56            TransactionFilterValue::String(v) => serializer.serialize_str(v),
57            TransactionFilterValue::Int(v) => serializer.serialize_u64(*v),
58        }
59    }
60}
61
62pub const MAX_TX_FILTERS: usize = 32;
63
64#[derive(Serialize, Deserialize, Debug)]
65pub struct TransactionFilterItem {
66    pub field: String,
67    pub op: TransactionFilterOp,
68    pub value: TransactionFilterValue,
69}
70
71#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, JsonSchema)]
72/// Describes possible interchain query types
73pub enum QueryType {
74    #[serde(rename = "kv")]
75    /// **kv** is an interchain query type to query KV values from remote chain
76    KV,
77
78    /// **tx** is an interchain query type to query transactions from remote chain
79    #[serde(rename = "tx")]
80    TX,
81}
82
83#[allow(clippy::from_over_into)]
84impl Into<String> for QueryType {
85    fn into(self) -> String {
86        match self {
87            QueryType::KV => QUERY_TYPE_KV_VALUE.to_string(),
88            QueryType::TX => QUERY_TYPE_TX_VALUE.to_string(),
89        }
90    }
91}
92
93/// Describes possible interchain query types with a payload
94pub enum QueryPayload {
95    /// **kv** is an interchain query type to query KV values from remote chain
96    /// payload is kvkeys
97    KV(Vec<KVKey>),
98
99    /// **tx** is an interchain query type to query transactions from remote chain
100    /// payload is transactions filter
101    TX(Vec<TransactionFilterItem>),
102}
103
104/// Bytes representations of Bech32 address
105pub type AddressBytes = Vec<u8>;
106
107/// A **data structure** that can be reconstructed from slice of **StorageValue** structures.
108/// Neutron provides `KVReconstruct` for many primitive and standard Cosmos-SDK types and query responses.
109///
110/// Third-party projects may provide `KVReconstruct` implementations for types that they introduce.
111/// For example if some query is not implemented in Neutron standard library, developers can create their own type/query and implement `KVReconstruct` for it.
112///
113///
114/// Usually used together with `query_kv_result` function. For example, there is an Interchain Query with some `query_id` to query balance from remote chain.
115/// And there is an implemented `KVReconstruct` for `Balance` structure.
116/// So you can easily get reconstructed response for the query just in one line:
117/// ```rust ignore
118/// let balances: Balances = query_kv_result(deps, query_id)?;
119/// ```
120///
121/// Anyone can implement `KVReconstruct` for any type and use `query_kv_result` without any problems.
122pub trait KVReconstruct: Sized {
123    /// Reconstructs this value from the slice of **StorageValue**'s.
124    fn reconstruct(kvs: &[StorageValue]) -> NeutronResult<Self>;
125}
126
127impl KVReconstruct for Uint128 {
128    fn reconstruct(storage_values: &[StorageValue]) -> NeutronResult<Uint128> {
129        let value = storage_values
130            .first()
131            .ok_or_else(|| StdError::generic_err("empty query result"))?;
132        let balance: Uint128 = from_json(&value.value)?;
133        Ok(balance)
134    }
135}