router-wasm-bindings 1.0.3

Bindings for CustomMsg and CustomQuery for the Router blockchain
Documentation
use cosmwasm_std::{Deps, StdError, StdResult};

use crate::{
    types::{ChainType, GasPriceResponse, TokenPriceResponse, EVM_ADDRESS_LENGTH},
    Bytes, RouterQuerier, RouterQuery,
};
// use bech32::{self, u5, FromBase32, ToBase32, Variant};
use bech32::{self, Bech32, Hrp};

const SOL_ADDRESS_LENGTH: usize = 32;

pub fn convert_address_from_string_to_bytes(address: String, chain_type: u64) -> StdResult<Bytes> {
    if chain_type == ChainType::ChainTypeEvm.get_chain_code()
        || chain_type == ChainType::ChainTypeTron.get_chain_code()
    {
        let eth_address: String = address.replace("0x", "");
        let eth_address: String = eth_address.replace("0X", "");
        match hex::decode(eth_address) {
            Ok(addr) => {
                if addr.len() != EVM_ADDRESS_LENGTH {
                    return Err(StdError::generic_err("Invalid EVM address length"));
                }
                return Ok(addr);
            }
            Err(err) => {
                return Err(StdError::generic_err(err.to_string()));
            }
        };
    } else if chain_type == ChainType::ChainTypeSolana.get_chain_code() {
        let sol_address: String = address.replace("0x", "");
        let sol_address: String = sol_address.replace("0X", "");
        match hex::decode(sol_address) {
            Ok(addr) => {
                if addr.len() != SOL_ADDRESS_LENGTH {
                    return Err(StdError::generic_err("Invalid SOL address length"));
                }
                return Ok(addr);
            }
            Err(err) => {
                return Err(StdError::generic_err(err.to_string()));
            }
        };
    } else {
        return Ok(address.as_bytes().to_vec());
    }
}

pub fn convert_address_from_bytes_to_string(address: &[u8], chain_type: u64) -> StdResult<String> {
    if chain_type == ChainType::ChainTypeEvm.get_chain_code()
        || chain_type == ChainType::ChainTypeTron.get_chain_code()
    {
        if address.len() != EVM_ADDRESS_LENGTH {
            return Err(StdError::generic_err("Invalid EVM address length"));
        }
        return Ok("0x".to_string() + &hex::encode(address.to_vec()));
    } else if chain_type == ChainType::ChainTypeSolana.get_chain_code() {
        if address.len() != SOL_ADDRESS_LENGTH {
            return Err(StdError::generic_err("Invalid SOL address length"));
        }
        return Ok("0x".to_string() + &hex::encode(address.to_vec()));
    } else {
        match String::from_utf8(address.to_vec()) {
            Ok(addr) => return Ok(addr),
            Err(err) => {
                return Err(StdError::generic_err(err.to_string()));
            }
        }
    }
}

pub fn evm_address_to_router_address(address: &[u8]) -> StdResult<String> {
    if address.len() != EVM_ADDRESS_LENGTH {
        return Err(StdError::generic_err("Invalid EVM address length"));
    }
    let new_hp = Hrp::parse("router").unwrap();
    match bech32::encode::<Bech32>(new_hp, &address) {
        Ok(router_address) => Ok(router_address),
        Err(err) => StdResult::Err(StdError::generic_err(err.to_string())),
    }
}

pub fn router_address_to_evm_address(router_address: &str) -> StdResult<Vec<u8>> {
    let decoding_result = bech32::decode(router_address);
    if decoding_result.is_err() {
        return StdResult::Err(StdError::generic_err(
            "Invalid bech32 Address Provided, bech32 Decoding error",
        ));
    }
    let (hrp_value, decoded_address) = decoding_result.unwrap();
    if hrp_value.as_str() != "router" {
        return StdResult::Err(StdError::generic_err("Invalid Router Address Provided"));
    }
    if decoded_address.len() != EVM_ADDRESS_LENGTH {
        return Err(StdError::generic_err("Invalid EVM address length"));
    }
    return Ok(decoded_address);
}

pub fn fetch_oracle_gas_price(
    deps: Deps<RouterQuery>,
    chain_id: String,
) -> StdResult<GasPriceResponse> {
    let router_querier: RouterQuerier = RouterQuerier::new(&deps.querier);
    router_querier.gas_price(chain_id)
}

pub fn fetch_oracle_token_price(
    deps: Deps<RouterQuery>,
    symbol: String,
) -> StdResult<TokenPriceResponse> {
    let router_querier: RouterQuerier = RouterQuerier::new(&deps.querier);
    router_querier.token_price(symbol)
}