dao_proposal_hooks/
lib.rs

1#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
2
3use cosmwasm_schema::cw_serde;
4use cosmwasm_std::{to_binary, StdResult, Storage, SubMsg, WasmMsg};
5use cw_hooks::Hooks;
6use dao_voting::reply::mask_proposal_hook_index;
7
8#[cw_serde]
9pub enum ProposalHookMsg {
10    NewProposal {
11        id: u64,
12        proposer: String,
13    },
14    ProposalStatusChanged {
15        id: u64,
16        old_status: String,
17        new_status: String,
18    },
19}
20
21// This is just a helper to properly serialize the above message
22#[cw_serde]
23pub enum ProposalHookExecuteMsg {
24    ProposalHook(ProposalHookMsg),
25}
26
27/// Prepares new proposal hook messages. These messages reply on error
28/// and have even reply IDs.
29/// IDs are set to even numbers to then be interleaved with the vote hooks.
30pub fn new_proposal_hooks(
31    hooks: Hooks,
32    storage: &dyn Storage,
33    id: u64,
34    proposer: &str,
35) -> StdResult<Vec<SubMsg>> {
36    let msg = to_binary(&ProposalHookExecuteMsg::ProposalHook(
37        ProposalHookMsg::NewProposal {
38            id,
39            proposer: proposer.to_string(),
40        },
41    ))?;
42
43    let mut index: u64 = 0;
44    let messages = hooks.prepare_hooks(storage, |a| {
45        let execute = WasmMsg::Execute {
46            contract_addr: a.to_string(),
47            msg: msg.clone(),
48            funds: vec![],
49        };
50        let masked_index = mask_proposal_hook_index(index);
51        let tmp = SubMsg::reply_on_error(execute, masked_index);
52        index += 1;
53        Ok(tmp)
54    })?;
55
56    Ok(messages)
57}
58
59/// Prepares proposal status hook messages. These messages reply on error
60/// and have even reply IDs.
61/// IDs are set to even numbers to then be interleaved with the vote hooks.
62pub fn proposal_status_changed_hooks(
63    hooks: Hooks,
64    storage: &dyn Storage,
65    id: u64,
66    old_status: String,
67    new_status: String,
68) -> StdResult<Vec<SubMsg>> {
69    if old_status == new_status {
70        return Ok(vec![]);
71    }
72
73    let msg = to_binary(&ProposalHookExecuteMsg::ProposalHook(
74        ProposalHookMsg::ProposalStatusChanged {
75            id,
76            old_status,
77            new_status,
78        },
79    ))?;
80    let mut index: u64 = 0;
81    let messages = hooks.prepare_hooks(storage, |a| {
82        let execute = WasmMsg::Execute {
83            contract_addr: a.to_string(),
84            msg: msg.clone(),
85            funds: vec![],
86        };
87        let masked_index = mask_proposal_hook_index(index);
88        let tmp = SubMsg::reply_on_error(execute, masked_index);
89        index += 1;
90        Ok(tmp)
91    })?;
92
93    Ok(messages)
94}