cw4_group/
helpers.rs

1use std::ops::Deref;
2
3use cosmwasm_schema::cw_serde;
4use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg};
5use cw4::{Cw4Contract, Member};
6
7use crate::{msg::ExecuteMsg, ContractError};
8
9/// Cw4GroupContract is a wrapper around Cw4Contract that provides a lot of helpers
10/// for working with cw4-group contracts.
11///
12/// It extends Cw4Contract to add the extra calls from cw4-group.
13#[cw_serde]
14pub struct Cw4GroupContract(pub Cw4Contract);
15
16impl Deref for Cw4GroupContract {
17    type Target = Cw4Contract;
18
19    fn deref(&self) -> &Self::Target {
20        &self.0
21    }
22}
23
24impl Cw4GroupContract {
25    pub fn new(addr: Addr) -> Self {
26        Cw4GroupContract(Cw4Contract(addr))
27    }
28
29    fn encode_msg(&self, msg: ExecuteMsg) -> StdResult<CosmosMsg> {
30        Ok(WasmMsg::Execute {
31            contract_addr: self.addr().into(),
32            msg: to_json_binary(&msg)?,
33            funds: vec![],
34        }
35        .into())
36    }
37
38    pub fn update_members(&self, remove: Vec<String>, add: Vec<Member>) -> StdResult<CosmosMsg> {
39        let msg = ExecuteMsg::UpdateMembers { remove, add };
40        self.encode_msg(msg)
41    }
42}
43
44/// Sorts the slice and verifies all member addresses are unique.
45pub fn validate_unique_members(members: &mut [Member]) -> Result<(), ContractError> {
46    members.sort_by(|a, b| a.addr.cmp(&b.addr));
47    for (a, b) in members.iter().zip(members.iter().skip(1)) {
48        if a.addr == b.addr {
49            return Err(ContractError::DuplicateMember {
50                member: a.addr.clone(),
51            });
52        }
53    }
54
55    Ok(())
56}