1use crate::types::Metadata;
2use cosmwasm_schema::cw_serde;
3use cosmwasm_std::{Binary, CosmosMsg, CustomMsg, StdResult, Uint128};
4
5#[cw_serde]
7pub enum TokenFactoryMsg {
8 CreateDenom {
19 subdenom: String,
20 metadata: Option<Metadata>,
22 },
23 ChangeAdmin {
27 denom: String,
28 new_admin_address: String,
29 },
30 MintTokens {
33 denom: String,
34 amount: Uint128,
35 mint_to_address: String,
36 },
37 BurnTokens {
40 denom: String,
41 amount: Uint128,
42 burn_from_address: String,
43 },
44 ForceTransfer {
47 denom: String,
48 amount: Uint128,
49 from_address: String,
50 to_address: String,
51 },
52 SetMetadata {
53 denom: String,
54 metadata: Metadata,
55 },
56}
57
58impl TokenFactoryMsg {
59 pub fn mint_contract_tokens(denom: String, amount: Uint128, mint_to_address: String) -> Self {
60 TokenFactoryMsg::MintTokens {
61 denom,
62 amount,
63 mint_to_address,
64 }
65 }
66
67 pub fn burn_contract_tokens(denom: String, amount: Uint128, burn_from_address: String) -> Self {
68 TokenFactoryMsg::BurnTokens {
69 denom,
70 amount,
71 burn_from_address,
72 }
73 }
74
75 pub fn force_transfer_tokens(
76 denom: String,
77 amount: Uint128,
78 from_address: String,
79 to_address: String,
80 ) -> Self {
81 TokenFactoryMsg::ForceTransfer {
82 denom,
83 amount,
84 from_address,
85 to_address,
86 }
87 }
88}
89
90impl From<TokenFactoryMsg> for CosmosMsg<TokenFactoryMsg> {
91 fn from(msg: TokenFactoryMsg) -> CosmosMsg<TokenFactoryMsg> {
92 CosmosMsg::Custom(msg)
93 }
94}
95
96impl CustomMsg for TokenFactoryMsg {}
97
98pub struct CreateDenomResponse {
101 pub new_token_denom: String,
102}
103
104impl CreateDenomResponse {
105 pub fn from_reply_data(data: Binary) -> StdResult<Self> {
107 let mut data = Vec::from(data);
109 let new_token_denom = copied_from_cw_utils::parse_protobuf_string(&mut data, 1)?;
111 Ok(CreateDenomResponse { new_token_denom })
112 }
113
114 pub fn encode(&self) -> StdResult<Binary> {
115 Ok(b"".into())
117 }
118}
119
120mod copied_from_cw_utils {
122 use cosmwasm_std::{StdError, StdResult};
123
124 const WIRE_TYPE_LENGTH_DELIMITED: u8 = 2;
126 const VARINT_MAX_BYTES: usize = 9;
128
129 pub fn parse_protobuf_string(data: &mut Vec<u8>, field_number: u8) -> StdResult<String> {
130 let str_field = parse_protobuf_length_prefixed(data, field_number)?;
131 Ok(String::from_utf8(str_field)?)
132 }
133
134 fn parse_protobuf_length_prefixed(data: &mut Vec<u8>, field_number: u8) -> StdResult<Vec<u8>> {
137 if data.is_empty() {
138 return Ok(vec![]);
139 };
140 let mut rest_1 = data.split_off(1);
141 let wire_type = data[0] & 0b11;
142 let field = data[0] >> 3;
143
144 if field != field_number {
145 return Err(StdError::parse_err(
146 "length_prefix_field",
147 format!(
148 "failed to decode Protobuf message: invalid field #{} for field #{}",
149 field, field_number
150 ),
151 ));
152 }
153 if wire_type != WIRE_TYPE_LENGTH_DELIMITED {
154 return Err(StdError::parse_err(
155 "length_prefix_field",
156 format!(
157 "failed to decode Protobuf message: field #{}: invalid wire type {}",
158 field_number, wire_type
159 ),
160 ));
161 }
162
163 let len = parse_protobuf_varint(&mut rest_1, field_number)?;
164 if rest_1.len() < len {
165 return Err(StdError::parse_err(
166 "length_prefix_field",
167 format!(
168 "failed to decode Protobuf message: field #{}: message too short",
169 field_number
170 ),
171 ));
172 }
173 *data = rest_1.split_off(len);
174
175 Ok(rest_1)
176 }
177
178 fn parse_protobuf_varint(data: &mut Vec<u8>, field_number: u8) -> StdResult<usize> {
181 let data_len = data.len();
182 let mut len: u64 = 0;
183 let mut i = 0;
184 while i < VARINT_MAX_BYTES {
185 if data_len == i {
186 return Err(StdError::parse_err(
187 "varint",
188 format!(
189 "failed to decode Protobuf message: field #{}: varint data too short",
190 field_number
191 ),
192 ));
193 }
194 len += ((data[i] & 0x7f) as u64) << (i * 7);
195 if data[i] & 0x80 == 0 {
196 break;
197 }
198 i += 1;
199 }
200 if i == VARINT_MAX_BYTES {
201 return Err(StdError::parse_err(
202 "varint",
203 format!(
204 "failed to decode Protobuf message: field #{}: varint data too long",
205 field_number
206 ),
207 ));
208 }
209 *data = data[i + 1..].to_owned();
210
211 Ok(len as usize) }
213}