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#[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
44pub 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}