use crate::errors::error::{NeutronError, NeutronResult};
use crate::interchain_queries::types::{
AddressBytes, BALANCES_PREFIX, DELEGATION_KEY, FEE_POOL_KEY, MAX_ADDR_LEN,
PARAMS_STORE_DELIMITER, PROPOSALS_KEY_PREFIX, SUPPLY_PREFIX, VALIDATORS_KEY,
};
use cosmos_sdk_proto::cosmos::staking::v1beta1::Commission as ValidatorCommission;
use cosmwasm_std::{Binary, Decimal, Uint128};
use std::str::{from_utf8, FromStr};
pub fn create_params_store_key(module: &str, key: &str) -> Vec<u8> {
let mut s = String::with_capacity(module.len() + 1 + key.len());
s.push_str(module);
s.push_str(PARAMS_STORE_DELIMITER);
s.push_str(key);
s.into_bytes()
}
pub fn decode_and_convert(encoded: &str) -> NeutronResult<AddressBytes> {
let (_hrp, bytes, _variant) = bech32::decode(encoded)?;
Ok(bech32::convert_bits(&bytes, 5, 8, false)?)
}
pub fn length_prefix<AddrBytes: AsRef<[u8]>>(addr: AddrBytes) -> NeutronResult<Vec<u8>> {
let bz_length = addr.as_ref().len();
if bz_length == 0 {
return Ok(vec![]);
}
if bz_length > MAX_ADDR_LEN {
return Err(NeutronError::MaxAddrLength {
max: MAX_ADDR_LEN,
actual: bz_length,
});
}
let mut p: Vec<u8> = vec![bz_length as u8];
p.extend_from_slice(addr.as_ref());
Ok(p)
}
pub fn create_account_balances_prefix<AddrBytes: AsRef<[u8]>>(
addr: AddrBytes,
) -> NeutronResult<Vec<u8>> {
let mut prefix: Vec<u8> = vec![BALANCES_PREFIX];
prefix.extend_from_slice(length_prefix(addr)?.as_slice());
Ok(prefix)
}
pub fn create_account_denom_balance_key<AddrBytes: AsRef<[u8]>, S: AsRef<str>>(
addr: AddrBytes,
denom: S,
) -> NeutronResult<Vec<u8>> {
let mut account_balance_key = create_account_balances_prefix(addr)?;
account_balance_key.extend_from_slice(denom.as_ref().as_bytes());
Ok(account_balance_key)
}
pub fn create_denom_balance_key<AddrBytes: AsRef<[u8]>, S: AsRef<str>>(
addr: AddrBytes,
denom: S,
) -> NeutronResult<Vec<u8>> {
let mut account_balance_key = create_account_balances_prefix(addr)?;
account_balance_key.extend_from_slice(denom.as_ref().as_bytes());
Ok(account_balance_key)
}
pub fn create_total_denom_key<S: AsRef<str>>(denom: S) -> NeutronResult<Vec<u8>> {
let mut total_supply: Vec<u8> = vec![SUPPLY_PREFIX];
total_supply.extend_from_slice(denom.as_ref().as_bytes());
Ok(total_supply)
}
pub fn create_delegations_key<AddrBytes: AsRef<[u8]>>(
delegator_address: AddrBytes,
) -> NeutronResult<Vec<u8>> {
let mut key: Vec<u8> = vec![DELEGATION_KEY];
key.extend_from_slice(length_prefix(delegator_address)?.as_slice());
Ok(key)
}
pub fn create_delegation_key<AddrBytes: AsRef<[u8]>>(
delegator_address: AddrBytes,
validator_address: AddrBytes,
) -> NeutronResult<Vec<u8>> {
let mut delegations_key: Vec<u8> = create_delegations_key(delegator_address)?;
delegations_key.extend_from_slice(length_prefix(validator_address)?.as_slice());
Ok(delegations_key)
}
pub fn create_validator_key<AddrBytes: AsRef<[u8]>>(
operator_address: AddrBytes,
) -> NeutronResult<Vec<u8>> {
let mut key: Vec<u8> = vec![VALIDATORS_KEY];
key.extend_from_slice(length_prefix(operator_address)?.as_slice());
Ok(key)
}
pub fn create_fee_pool_key() -> NeutronResult<Vec<u8>> {
let key: Vec<u8> = vec![FEE_POOL_KEY];
Ok(key)
}
pub fn create_gov_proposal_key(proposal_id: u64) -> NeutronResult<Vec<u8>> {
let mut key: Vec<u8> = vec![PROPOSALS_KEY_PREFIX];
key.extend_from_slice(proposal_id.to_be_bytes().as_slice());
Ok(key)
}
pub fn get_max_change_rate(commission: &Option<ValidatorCommission>) -> Option<Decimal> {
let commission_rates = commission.as_ref().map(|v| v.commission_rates.as_ref())?;
commission_rates.map(|v| Decimal::from_str(v.max_change_rate.as_str()).unwrap_or_default())
}
pub fn get_max_rate(commission: &Option<ValidatorCommission>) -> Option<Decimal> {
let commission_rates = commission.as_ref().map(|v| v.commission_rates.as_ref())?;
commission_rates.map(|v| Decimal::from_str(v.max_rate.as_str()).unwrap_or_default())
}
pub fn get_rate(commission: &Option<ValidatorCommission>) -> Option<Decimal> {
let commission_rates = commission.as_ref().map(|v| v.commission_rates.as_ref())?;
commission_rates.map(|v| Decimal::from_str(v.rate.as_str()).unwrap_or_default())
}
pub fn get_update_time(commission: &Option<ValidatorCommission>) -> Option<u64> {
let commission_rates = commission.as_ref().map(|v| v.update_time.as_ref())?;
commission_rates.map(|v| v.seconds as u64)
}
pub fn get_total_supply_denom(denom: &Binary) -> Option<String> {
if denom.len() > 1 {
return from_utf8(&denom[1..]).ok().map(|d| d.to_string());
}
None
}
pub fn get_total_supply_amount(amount: &Binary) -> Option<Uint128> {
from_utf8(amount).ok().map(|a| Uint128::from_str(a).ok())?
}