cosmwasm_std/query/
staking.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::prelude::*;
5use crate::{Addr, Coin, Decimal};
6
7use super::query_response::QueryResponseType;
8
9use crate::utils::impl_hidden_constructor;
10
11#[non_exhaustive]
12#[derive(
13    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
14)]
15#[serde(rename_all = "snake_case")]
16pub enum StakingQuery {
17    /// Returns the denomination that can be bonded (if there are multiple native tokens on the chain)
18    BondedDenom {},
19    /// AllDelegations will return all delegations by the delegator
20    AllDelegations { delegator: String },
21    /// Delegation will return more detailed info on a particular
22    /// delegation, defined by delegator/validator pair
23    Delegation {
24        delegator: String,
25        validator: String,
26    },
27    /// Returns all validators in the currently active validator set.
28    ///
29    /// The query response type is `AllValidatorsResponse`.
30    AllValidators {},
31    /// Returns the validator at the given address. Returns None if the validator is
32    /// not part of the currently active validator set.
33    ///
34    /// The query response type is `ValidatorResponse`.
35    Validator {
36        /// The validator's address (e.g. (e.g. cosmosvaloper1...))
37        address: String,
38    },
39}
40
41/// BondedDenomResponse is data format returned from StakingRequest::BondedDenom query
42#[derive(
43    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
44)]
45#[serde(rename_all = "snake_case")]
46#[non_exhaustive]
47pub struct BondedDenomResponse {
48    pub denom: String,
49}
50
51impl QueryResponseType for BondedDenomResponse {}
52
53impl_hidden_constructor!(BondedDenomResponse, denom: String);
54
55/// DelegationsResponse is data format returned from StakingRequest::AllDelegations query
56#[derive(
57    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
58)]
59#[serde(rename_all = "snake_case")]
60#[non_exhaustive]
61pub struct AllDelegationsResponse {
62    pub delegations: Vec<Delegation>,
63}
64
65impl QueryResponseType for AllDelegationsResponse {}
66
67impl_hidden_constructor!(AllDelegationsResponse, delegations: Vec<Delegation>);
68
69/// Delegation is basic (cheap to query) data about a delegation.
70///
71/// Instances are created in the querier.
72#[derive(
73    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
74)]
75#[non_exhaustive]
76pub struct Delegation {
77    pub delegator: Addr,
78    /// A validator address (e.g. cosmosvaloper1...)
79    pub validator: String,
80    /// How much we have locked in the delegation
81    pub amount: Coin,
82}
83
84impl_hidden_constructor!(Delegation, delegator: Addr, validator: String, amount: Coin);
85
86impl From<FullDelegation> for Delegation {
87    fn from(full: FullDelegation) -> Self {
88        Delegation {
89            delegator: full.delegator,
90            validator: full.validator,
91            amount: full.amount,
92        }
93    }
94}
95
96/// DelegationResponse is data format returned from StakingRequest::Delegation query
97#[derive(
98    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
99)]
100#[serde(rename_all = "snake_case")]
101#[non_exhaustive]
102pub struct DelegationResponse {
103    pub delegation: Option<FullDelegation>,
104}
105
106impl QueryResponseType for DelegationResponse {}
107
108impl_hidden_constructor!(DelegationResponse, delegation: Option<FullDelegation>);
109
110/// FullDelegation is all the info on the delegation, some (like accumulated_reward and can_redelegate)
111/// is expensive to query.
112///
113/// Instances are created in the querier.
114#[derive(
115    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
116)]
117#[non_exhaustive]
118pub struct FullDelegation {
119    pub delegator: Addr,
120    /// A validator address (e.g. cosmosvaloper1...)
121    pub validator: String,
122    /// How much we have locked in the delegation
123    pub amount: Coin,
124    /// can_redelegate captures how much can be immediately redelegated.
125    /// 0 is no redelegation and can_redelegate == amount is redelegate all
126    /// but there are many places between the two
127    pub can_redelegate: Coin,
128    /// How much we can currently withdraw
129    pub accumulated_rewards: Vec<Coin>,
130}
131
132impl_hidden_constructor!(
133    FullDelegation,
134    delegator: Addr,
135    validator: String,
136    amount: Coin,
137    can_redelegate: Coin,
138    accumulated_rewards: Vec<Coin>
139);
140
141impl FullDelegation {
142    /// Creates a new delegation.
143    ///
144    /// If fields get added to the [`FullDelegation`] struct in the future, this constructor will
145    /// provide default values for them, but these default values may not be sensible.
146    pub fn create(
147        delegator: Addr,
148        validator: String,
149        amount: Coin,
150        can_redelegate: Coin,
151        accumulated_rewards: Vec<Coin>,
152    ) -> Self {
153        Self {
154            delegator,
155            validator,
156            amount,
157            can_redelegate,
158            accumulated_rewards,
159        }
160    }
161}
162
163/// The data format returned from StakingRequest::AllValidators query
164#[derive(
165    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
166)]
167#[non_exhaustive]
168pub struct AllValidatorsResponse {
169    pub validators: Vec<ValidatorMetadata>,
170}
171
172impl QueryResponseType for AllValidatorsResponse {}
173
174impl_hidden_constructor!(AllValidatorsResponse, validators: Vec<ValidatorMetadata>);
175
176/// The data format returned from StakingRequest::Validator query
177#[derive(
178    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
179)]
180#[non_exhaustive]
181pub struct ValidatorResponse {
182    pub validator: Option<Validator>,
183}
184
185impl QueryResponseType for ValidatorResponse {}
186
187impl_hidden_constructor!(ValidatorResponse, validator: Option<Validator>);
188
189/// Instances are created in the querier.
190#[derive(
191    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
192)]
193#[non_exhaustive]
194pub struct ValidatorMetadata {
195    /// The operator address of the validator (e.g. cosmosvaloper1...).
196    /// See https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/proto/cosmos/staking/v1beta1/staking.proto#L95-L96
197    /// for more information.
198    ///
199    /// This uses `String` instead of `Addr` since the bech32 address prefix is different from
200    /// the ones that regular user accounts use.
201    pub address: String,
202    pub commission: Decimal,
203    pub max_commission: Decimal,
204    /// The maximum daily increase of the commission
205    pub max_change_rate: Decimal,
206}
207
208impl_hidden_constructor!(
209    ValidatorMetadata,
210    address: String,
211    commission: Decimal,
212    max_commission: Decimal,
213    max_change_rate: Decimal
214);
215
216/// Instances are created in the querier.
217#[derive(
218    Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
219)]
220#[non_exhaustive]
221pub struct Validator {
222    /// The operator address of the validator (e.g. cosmosvaloper1...).
223    /// See https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/proto/cosmos/staking/v1beta1/staking.proto#L95-L96
224    /// for more information.
225    ///
226    /// This uses `String` instead of `Addr` since the bech32 address prefix is different from
227    /// the ones that regular user accounts use.
228    pub address: String,
229    pub commission: Decimal,
230    pub max_commission: Decimal,
231    /// The maximum daily increase of the commission
232    pub max_change_rate: Decimal,
233}
234
235impl Validator {
236    /// Creates a new validator.
237    ///
238    /// If fields get added to the [`Validator`] struct in the future, this constructor will
239    /// provide default values for them, but these default values may not be sensible.
240    pub fn create(
241        address: String,
242        commission: Decimal,
243        max_commission: Decimal,
244        max_change_rate: Decimal,
245    ) -> Self {
246        Self {
247            address,
248            commission,
249            max_commission,
250            max_change_rate,
251        }
252    }
253}
254
255impl_hidden_constructor!(
256    Validator,
257    address: String,
258    commission: Decimal,
259    max_commission: Decimal,
260    max_change_rate: Decimal
261);
262
263// Validator should contain all data that ValidatorMetadata has + maybe some additional data
264// that is expensive to query, so we can convert ValidatorMetadata to Validator easily.
265impl From<Validator> for ValidatorMetadata {
266    fn from(validator: Validator) -> Self {
267        ValidatorMetadata {
268            address: validator.address,
269            commission: validator.commission,
270            max_commission: validator.max_commission,
271            max_change_rate: validator.max_change_rate,
272        }
273    }
274}