use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; use cw_orch::prelude::*; use msg::{ execute::{BaseExecMsg, BaseExecMsgFns as _, MintingExecMsg, MintingExecMsgFns as _}, query::{ BalanceResponse, BaseQueryMsg, BaseQueryMsgFns as _, MinterResponse, MintingQueryMsg, MintingQueryMsgFns as _, }, }; #[cw_orch::interface(Empty, ExecuteMsg, QueryMsg, Empty)] pub struct Cw20; #[cw_orch::interface(Empty, MintingExecMsg, Empty, Empty)] pub struct Cw20Minter; #[cw_orch::interface(Empty, BaseExecMsg, Empty, Empty)] pub struct Cw20Base; pub fn instantiate( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: Empty, ) -> StdResult { Ok(Response::new().add_attribute("action", "instantiate")) } pub fn execute( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: ExecuteMsg, ) -> StdResult { Ok(Response::new()) } pub fn minter_execute( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: MintingExecMsg, ) -> StdResult { Ok(Response::new()) } pub fn base_execute( _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: BaseExecMsg, ) -> StdResult { Ok(Response::new()) } pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::Minting(minting) => match minting { MintingQueryMsg::Minter {} => to_json_binary(&MinterResponse { minter: "minter".to_string(), }), }, QueryMsg::Base(base_msg) => match base_msg { BaseQueryMsg::Balance { address: _ } => to_json_binary(&BalanceResponse { balance: 167u128.into(), }), }, } } pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult { Ok(Response::new()) } impl Uploadable for Cw20 { /// Returns a CosmWasm contract wrapper fn wrapper() -> Box> { Box::new(ContractWrapper::new_with_empty(execute, instantiate, query).with_migrate(migrate)) } } impl Uploadable for Cw20Minter { /// Returns a CosmWasm contract wrapper fn wrapper() -> Box> { Box::new( ContractWrapper::new_with_empty(minter_execute, instantiate, query) .with_migrate(migrate), ) } } impl Uploadable for Cw20Base { /// Returns a CosmWasm contract wrapper fn wrapper() -> Box> { Box::new( ContractWrapper::new_with_empty(base_execute, instantiate, query).with_migrate(migrate), ) } } pub fn main() -> anyhow::Result<()> { let mock = MockBech32::new("mock"); let contract = Cw20::new("cw20", mock.clone()); contract.upload()?; contract.instantiate(&Empty {}, None, &[])?; contract.mint(150_100u128, "nicoco")?; contract.send(150_100u128, "nicoco", Binary::from_base64("cXNk")?)?; let minter_response = contract.minter()?; let balance = contract.balance("nicoco")?; assert_eq!(minter_response.minter, "minter"); assert_eq!(balance.balance.u128(), 167); let contract = Cw20Minter::new("cw20_minter", mock.clone()); contract.upload()?; contract.instantiate(&Empty {}, None, &[])?; contract.mint(150_100u128, "nicoco")?; let contract = Cw20Base::new("cw20_base", mock.clone()); contract.upload()?; contract.instantiate(&Empty {}, None, &[])?; contract.send(150_100u128, "nicoco", Binary::from_base64("cXNk")?)?; Ok(()) } #[cw_serde] pub enum ExecuteMsg { Minting(MintingExecMsg), Base(BaseExecMsg), } impl From for ExecuteMsg { fn from(value: MintingExecMsg) -> Self { Self::Minting(value) } } impl From for ExecuteMsg { fn from(value: BaseExecMsg) -> Self { Self::Base(value) } } #[cw_serde] pub enum QueryMsg { Minting(MintingQueryMsg), Base(BaseQueryMsg), } impl From for QueryMsg { fn from(value: MintingQueryMsg) -> Self { Self::Minting(value) } } impl From for QueryMsg { fn from(value: BaseQueryMsg) -> Self { Self::Base(value) } } mod msg { pub mod execute { use cosmwasm_schema::cw_serde; use cosmwasm_std::{Binary, Uint128}; #[cw_serde] #[derive(cw_orch::ExecuteFns)] pub enum MintingExecMsg { Mint { recipient: String, amount: Uint128 }, } #[cw_serde] #[derive(cw_orch::ExecuteFns)] pub enum BaseExecMsg { Send { contract: String, amount: Uint128, msg: Binary, }, } } pub mod query { use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; #[cw_serde] #[derive(QueryResponses, cw_orch::QueryFns)] pub enum MintingQueryMsg { #[returns(MinterResponse)] Minter {}, } #[cw_serde] #[derive(QueryResponses, cw_orch::QueryFns)] pub enum BaseQueryMsg { #[returns(BalanceResponse)] Balance { address: String }, } #[cw_serde] pub struct MinterResponse { pub minter: String, } #[cw_serde] pub struct BalanceResponse { pub balance: Uint128, } } }