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