1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::{
3 to_json_binary, Addr, CosmosMsg, CustomQuery, QuerierWrapper, QueryRequest, StdResult, Uint128,
4 WasmMsg, WasmQuery,
5};
6
7use crate::{
8 AllowanceResponse, BalanceResponse, Cw20ExecuteMsg, Cw20QueryMsg, MinterResponse,
9 TokenInfoResponse,
10};
11
12#[cw_serde]
17pub struct Cw20Contract(pub Addr);
18
19impl Cw20Contract {
20 pub fn addr(&self) -> Addr {
21 self.0.clone()
22 }
23
24 pub fn call<T: Into<Cw20ExecuteMsg>>(&self, msg: T) -> StdResult<CosmosMsg> {
25 let msg = to_json_binary(&msg.into())?;
26 Ok(WasmMsg::Execute {
27 contract_addr: self.addr().into(),
28 msg,
29 funds: vec![],
30 }
31 .into())
32 }
33
34 fn encode_smart_query<CQ: CustomQuery>(
35 &self,
36 msg: Cw20QueryMsg,
37 ) -> StdResult<QueryRequest<CQ>> {
38 Ok(WasmQuery::Smart {
39 contract_addr: self.addr().into(),
40 msg: to_json_binary(&msg)?,
41 }
42 .into())
43 }
44
45 pub fn balance<T, CQ>(&self, querier: &QuerierWrapper<CQ>, address: T) -> StdResult<Uint128>
47 where
48 T: Into<String>,
49 CQ: CustomQuery,
50 {
51 let query = self.encode_smart_query(Cw20QueryMsg::Balance {
52 address: address.into(),
53 })?;
54 let res: BalanceResponse = querier.query(&query)?;
55 Ok(res.balance)
56 }
57
58 pub fn meta<CQ: CustomQuery>(
61 &self,
62 querier: &QuerierWrapper<CQ>,
63 ) -> StdResult<TokenInfoResponse> {
64 let query = self.encode_smart_query(Cw20QueryMsg::TokenInfo {})?;
65 querier.query(&query)
66 }
67
68 pub fn allowance<T, U, CQ>(
70 &self,
71 querier: &QuerierWrapper<CQ>,
72 owner: T,
73 spender: U,
74 ) -> StdResult<AllowanceResponse>
75 where
76 T: Into<String>,
77 U: Into<String>,
78 CQ: CustomQuery,
79 {
80 let query = self.encode_smart_query(Cw20QueryMsg::Allowance {
81 owner: owner.into(),
82 spender: spender.into(),
83 })?;
84 querier.query(&query)
85 }
86
87 pub fn minter<CQ: CustomQuery>(
89 &self,
90 querier: &QuerierWrapper<CQ>,
91 ) -> StdResult<Option<MinterResponse>> {
92 let query = self.encode_smart_query(Cw20QueryMsg::Minter {})?;
93 querier.query(&query)
94 }
95
96 pub fn has_allowance<CQ: CustomQuery>(&self, querier: &QuerierWrapper<CQ>) -> bool {
98 self.allowance(querier, self.addr(), self.addr()).is_ok()
99 }
100
101 pub fn is_mintable<CQ: CustomQuery>(&self, querier: &QuerierWrapper<CQ>) -> bool {
103 self.minter(querier).is_ok()
104 }
105}