1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{StdError, StdResult, Uint128};
5use cw20::{Cw20Coin, MinterResponse};
6
7#[derive(Serialize, Deserialize, JsonSchema)]
11pub struct InstantiateMsg {
12 pub name: String,
14 pub symbol: String,
16 pub decimals: u8,
18 pub initial_balances: Vec<Cw20Coin>,
20 pub mint: Option<MinterResponse>,
22}
23
24#[derive(Serialize, Deserialize, JsonSchema)]
28pub struct MigrateMsg {}
29
30impl InstantiateMsg {
31 pub fn get_cap(&self) -> Option<Uint128> {
32 self.mint.as_ref().and_then(|v| v.cap)
33 }
34
35 pub fn validate(&self) -> StdResult<()> {
36 if !is_valid_name(&self.name) {
38 return Err(StdError::generic_err(
39 "Name is not in the expected format (3-50 UTF-8 bytes)",
40 ));
41 }
42 if !is_valid_symbol(&self.symbol) {
43 return Err(StdError::generic_err(
44 "Ticker symbol is not in expected format [a-zA-Z\\-]{3,12}",
45 ));
46 }
47 if self.decimals > 18 {
48 return Err(StdError::generic_err("Decimals must not exceed 18"));
49 }
50 Ok(())
51 }
52}
53
54fn is_valid_name(name: &str) -> bool {
59 let bytes = name.as_bytes();
60 if bytes.len() < 3 || bytes.len() > 50 {
61 return false;
62 }
63 true
64}
65
66fn is_valid_symbol(symbol: &str) -> bool {
71 let bytes = symbol.as_bytes();
72 if bytes.len() < 3 || bytes.len() > 12 {
73 return false;
74 }
75 for byte in bytes.iter() {
76 if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) {
77 return false;
78 }
79 }
80 true
81}