astroport_types/
token.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{StdError, StdResult, Uint128};
5use cw20::{Cw20Coin, MinterResponse};
6
7/// TokenContract InstantiateMsg
8#[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        // Check name, symbol, decimals
27        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}