archway_bindings/
msg.rs

1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::{Coin, CosmosMsg, CustomMsg};
3
4/// Custom messages to interact with the Archway Network bindings.
5///
6/// Those messages work in conjunction with the `cosmwasm_std::CosmosMsg::Custom` variant.
7///
8/// # Examples
9///
10/// ```
11/// use cosmwasm_std::CosmosMsg;
12/// use archway_bindings::ArchwayMsg;
13///
14/// let msg: CosmosMsg<ArchwayMsg> = CosmosMsg::Custom(
15///     ArchwayMsg::UpdateContractMetadata {
16///         contract_address: Some(String::from("contract_address")),
17///         owner_address: Some(String::from("owner")),
18///         rewards_address: Some(String::from("rewards")),
19///     }
20/// );
21#[cw_serde]
22pub enum ArchwayMsg {
23    /// Updates a contract's metadata. Either `owner_address` or `rewards_address` must be provided.
24    UpdateContractMetadata {
25        /// If set to `None`, the metadata of the sender contract will be updated.
26        /// In case the `contract_address` already has a metadata, the sender contract must be set
27        /// as the `owner_address` to be able to update it.
28        contract_address: Option<String>,
29        /// If set to `None`, the contract's owner will not be updated.
30        owner_address: Option<String>,
31        /// If set to `None`, the contract's rewards address will not be updated.
32        rewards_address: Option<String>,
33    },
34    /// Sets a premium fee for a contract. This action should be executed from a contract only if
35    /// it's set as the `owner_address` in the metadata of `contract_address`. The tx will fail if
36    /// the `contract_address` has no metadata.
37    SetFlatFee {
38        contract_address: String,
39        flat_fee_amount: Coin,
40    },
41    /// Withdraws rewards from the contract. This action should be executed from a contract only if
42    /// it's set as the `rewards_address` in a contract metadata. Only one of `records_limit` or
43    /// `record_ids` should be set.
44    ///
45    /// # See also
46    ///
47    /// * [crate::types::rewards::WithdrawRewardsResponse]
48    WithdrawRewards {
49        /// Withdraw rewards up to a specified limit. If set to `None`, all rewards will be
50        /// withdrawn up to the limit of records specified by the governance parameter
51        /// `rewards.MaxWithdrawRecords`.
52        records_limit: Option<u64>,
53        /// Withdraw rewards by a list of record IDs.
54        record_ids: Vec<u64>,
55    },
56}
57
58impl CustomMsg for ArchwayMsg {}
59
60impl From<ArchwayMsg> for CosmosMsg<ArchwayMsg> {
61    fn from(msg: ArchwayMsg) -> Self {
62        CosmosMsg::Custom(msg)
63    }
64}
65
66impl ArchwayMsg {
67    /// Creates an `ArchwayMsg` to update the current contract's metadata ownership.
68    ///
69    /// # Arguments
70    ///
71    /// * `owner_address` - The new owner address.
72    pub fn update_rewards_ownership(owner_address: impl Into<String>) -> Self {
73        ArchwayMsg::UpdateContractMetadata {
74            contract_address: None,
75            owner_address: Some(owner_address.into()),
76            rewards_address: None,
77        }
78    }
79
80    /// Creates an `ArchwayMsg` to update the ownership of an external contract metadata.
81    ///
82    /// # Arguments
83    ///
84    /// * `contract_address` - The other contract address.
85    /// * `owner_address` - The new owner address.
86    pub fn update_external_rewards_ownership(
87        contract_address: impl Into<String>,
88        owner_address: impl Into<String>,
89    ) -> Self {
90        ArchwayMsg::UpdateContractMetadata {
91            contract_address: Some(contract_address.into()),
92            owner_address: Some(owner_address.into()),
93            rewards_address: None,
94        }
95    }
96
97    /// Creates an `ArchwayMsg` to update the current contract's rewards address.
98    ///
99    /// # Arguments
100    ///
101    /// * `rewards_address` - The new rewards address.
102    pub fn update_rewards_address(rewards_address: impl Into<String>) -> Self {
103        ArchwayMsg::UpdateContractMetadata {
104            contract_address: None,
105            owner_address: None,
106            rewards_address: Some(rewards_address.into()),
107        }
108    }
109
110    /// Creates an `ArchwayMsg` to update the rewards address of an external contract metadata.
111    ///
112    /// # Arguments
113    ///
114    /// * `contract_address` - The other contract address.
115    /// * `rewards_address` - The new rewards address.
116    pub fn update_external_rewards_address(
117        contract_address: impl Into<String>,
118        rewards_address: impl Into<String>,
119    ) -> Self {
120        ArchwayMsg::UpdateContractMetadata {
121            contract_address: Some(contract_address.into()),
122            owner_address: None,
123            rewards_address: Some(rewards_address.into()),
124        }
125    }
126
127    /// Creates an `ArchwayMsg` to set a flat fee for a contract.
128    ///
129    /// This action should be executed from a contract only if it's set as the `owner_address` in
130    /// the metadata of `contract_address`. The tx will fail if the `contract_address` has no
131    /// metadata.
132    ///
133    /// # Arguments
134    ///
135    /// * `contract_address` - The contract address.
136    /// * `amount` - The flat fee amount.
137    pub fn set_flat_fee(contract_address: impl Into<String>, amount: Coin) -> Self {
138        ArchwayMsg::SetFlatFee {
139            contract_address: contract_address.into(),
140            flat_fee_amount: amount,
141        }
142    }
143
144    /// Creates an `ArchwayMsg` to withdraw all rewards from the contract up to the maximum limit
145    /// of records specified by the governance parameter `rewards.MaxWithdrawRecords`.
146    ///
147    /// This action should be executed from a contract only if its set as the `rewards_address` in
148    /// a contract metadata.
149    pub fn withdraw_max_rewards() -> Self {
150        ArchwayMsg::WithdrawRewards {
151            records_limit: Some(0),
152            record_ids: vec![],
153        }
154    }
155
156    /// Creates an `ArchwayMsg` to withdraw rewards from the contract.
157    ///
158    /// This action should be executed from a contract only if its set as the `rewards_address` in
159    /// a contract metadata.
160    ///
161    /// # Arguments
162    ///
163    /// * `limit` - Withdraw rewards up to a specified limit.
164    pub fn withdraw_rewards_by_limit(limit: u64) -> Self {
165        ArchwayMsg::WithdrawRewards {
166            records_limit: Some(limit),
167            record_ids: vec![],
168        }
169    }
170
171    /// Creates an `ArchwayMsg` to withdraw rewards from the contract by a list of record IDs.
172    ///
173    /// This action should be executed from a contract only if its set as the `rewards_address` in
174    /// a contract metadata.
175    ///
176    /// # Arguments
177    ///
178    /// * `record_ids` - List of record IDs to withdraw rewards from the rewards pool.
179    pub fn withdraw_rewards_by_ids(record_ids: Vec<u64>) -> Self {
180        ArchwayMsg::WithdrawRewards {
181            records_limit: None,
182            record_ids,
183        }
184    }
185}
186
187#[cfg(test)]
188mod tests {
189    use super::*;
190
191    #[test]
192    fn from_archway_msg_works() {
193        let contract_address = String::from("contract_address");
194        let owner_address = String::from("owner");
195        let rewards_address = String::from("rewards");
196        let update_metadata = ArchwayMsg::UpdateContractMetadata {
197            contract_address: Some(contract_address),
198            owner_address: Some(owner_address),
199            rewards_address: Some(rewards_address),
200        };
201        let msg: CosmosMsg<ArchwayMsg> = update_metadata.clone().into();
202        match msg {
203            CosmosMsg::Custom(serialized_metadata) => {
204                assert_eq!(update_metadata, serialized_metadata)
205            }
206            _ => panic!("must encode in Custom variant"),
207        }
208    }
209}