astro4nit/
xastro_token.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{StdError, StdResult, Uint128};
5use cw20::{Cw20Coin, MinterResponse};
6
7/// ## Description
8/// This structure describes the parameters used for creating a xASTRO token contract.
9/// TokenContract InstantiateMsg
10#[derive(Serialize, Deserialize, JsonSchema)]
11pub struct InstantiateMsg {
12    /// Token name
13    pub name: String,
14    /// Token symbol
15    pub symbol: String,
16    /// The number of decimals the token has
17    pub decimals: u8,
18    /// Initial token balances
19    pub initial_balances: Vec<Cw20Coin>,
20    /// Token minting permissions
21    pub mint: Option<MinterResponse>,
22}
23
24/// ## Description
25/// This enum describes the query messages available in the contract.
26#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
27#[serde(rename_all = "snake_case")]
28pub enum QueryMsg {
29    /// Balance returns the current balance of a given address, 0 if unset.
30    Balance { address: String },
31    /// BalanceAt returns balance of the given address at the given block, 0 if unset.
32    BalanceAt { address: String, block: u64 },
33    /// TotalSupplyAt returns the total token supply at the given block.
34    TotalSupplyAt { block: u64 },
35    /// TokenInfo returns the contract's metadata - name, decimals, supply, etc.
36    TokenInfo {},
37    /// Returns who can mint and the hard cap on maximum tokens after minting.
38    Minter {},
39    /// Allowance returns an amount of tokens the spender can spend from the owner account, 0 if unset.
40    Allowance { owner: String, spender: String },
41    /// AllAllowances returns all allowances this owner has approved. Supports pagination.
42    AllAllowances {
43        owner: String,
44        start_after: Option<String>,
45        limit: Option<u32>,
46    },
47    /// AllAccounts returns all accounts that have balances. Supports pagination.
48    AllAccounts {
49        start_after: Option<String>,
50        limit: Option<u32>,
51    },
52    /// Returns marketing related contract metadata:
53    /// - description, logo, project url, etc.
54    MarketingInfo {},
55    /// Downloads embeded logo data (if stored on chain). Errors if no logo data was stored for this contract.
56    DownloadLogo {},
57}
58
59/// ## Description
60/// This structure describes a migration message.
61/// We currently take no arguments for migrations.
62#[derive(Serialize, Deserialize, JsonSchema)]
63pub struct MigrateMsg {}
64
65impl InstantiateMsg {
66    pub fn get_cap(&self) -> Option<Uint128> {
67        self.mint.as_ref().and_then(|v| v.cap)
68    }
69
70    pub fn validate(&self) -> StdResult<()> {
71        // Check name, symbol, decimals
72        if !is_valid_name(&self.name) {
73            return Err(StdError::generic_err(
74                "Name is not in the expected format (3-50 UTF-8 bytes)",
75            ));
76        }
77        if !is_valid_symbol(&self.symbol) {
78            return Err(StdError::generic_err(
79                "Ticker symbol is not in expected format [a-zA-Z\\-]{3,12}",
80            ));
81        }
82        if self.decimals > 18 {
83            return Err(StdError::generic_err("Decimals must not exceed 18"));
84        }
85        Ok(())
86    }
87}
88
89/// ## Description
90/// Checks the validity of a token's name
91/// ## Params
92/// * **name** is an object of type [`str`]. It is the token name to check
93fn is_valid_name(name: &str) -> bool {
94    let bytes = name.as_bytes();
95    if bytes.len() < 3 || bytes.len() > 50 {
96        return false;
97    }
98    true
99}
100
101/// ## Description
102/// Checks the validity of a token's symbol
103/// ## Params
104/// * **symbol** is an object of type [`str`]. It is the token symbol to check
105fn is_valid_symbol(symbol: &str) -> bool {
106    let bytes = symbol.as_bytes();
107    if bytes.len() < 3 || bytes.len() > 12 {
108        return false;
109    }
110    for byte in bytes.iter() {
111        if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) {
112            return false;
113        }
114    }
115    true
116}