router-wasm-bindings 1.0.3

Bindings for CustomMsg and CustomQuery for the Router blockchain
Documentation
use crate::Bytes;
use cosmwasm_std::{Coin, StdError, StdResult, Uint128};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
pub struct RequestMetaData {
    pub dest_gas_limit: u64,
    pub dest_gas_price: u64,
    pub ack_gas_limit: u64,
    pub ack_gas_price: u64,
    pub relayer_fee: Uint128,
    pub ack_type: AckType,
    pub is_read_call: bool,
    pub asm_address: String,
}

impl RequestMetaData {
    pub fn get_abi_encoded_bytes(&self) -> Bytes {
        let mut bytes: Bytes = vec![];
        bytes.append(&mut self.dest_gas_limit.to_be_bytes().to_vec());
        bytes.append(&mut self.dest_gas_price.to_be_bytes().to_vec());
        bytes.append(&mut self.ack_gas_limit.to_be_bytes().to_vec());
        bytes.append(&mut self.ack_gas_price.to_be_bytes().to_vec());
        bytes.append(&mut self.relayer_fee.u128().to_be_bytes().to_vec());
        bytes.append(&mut self.ack_type.get_ack_code().to_be_bytes().to_vec());
        if self.is_read_call {
            bytes.append(&mut vec![1]);
        } else {
            bytes.append(&mut vec![0]);
        }
        bytes.append(&mut self.asm_address.as_bytes().to_vec());
        return bytes;
    }

    pub fn from_abi_encoded_bytes(bytes: Bytes) -> StdResult<Self> {
        if bytes.len() < 50 {
            return Err(StdError::generic_err(
                "MetaData length should not be less than 50 bytes",
            ));
        }
        let mut le_bytes: [u8; 8] = [0; 8];
        le_bytes.copy_from_slice(&bytes[0..8]);
        let dest_gas_limit: u64 = u64::from_be_bytes(le_bytes);

        le_bytes.copy_from_slice(&bytes[8..16]);
        let dest_gas_price: u64 = u64::from_be_bytes(le_bytes);

        le_bytes.copy_from_slice(&bytes[16..24]);
        let ack_gas_limit: u64 = u64::from_be_bytes(le_bytes);

        le_bytes.copy_from_slice(&bytes[24..32]);
        let ack_gas_price: u64 = u64::from_be_bytes(le_bytes);

        let mut le_bytes: [u8; 16] = [0; 16];
        le_bytes.copy_from_slice(&bytes[32..48]);
        let relayer_fee: Uint128 = Uint128::from(u128::from_be_bytes(le_bytes));

        let le_bytes: [u8; 1] = [bytes[48]];
        let ack_type: AckType = AckType::get_ack_type(u8::from_be_bytes(le_bytes) as u64)?;

        let is_read_call: bool = if bytes[49] == 0 { false } else { true };
        let asm_bytes_vec: Bytes = bytes[50..bytes.len()].to_vec();
        let asm_address: String = String::from_utf8(asm_bytes_vec)?;
        Ok(Self {
            dest_gas_limit,
            dest_gas_price,
            ack_gas_limit,
            ack_gas_price,
            relayer_fee,
            ack_type,
            is_read_call,
            asm_address,
        })
    }
}

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
pub enum ChainType {
    ChainTypeNone,
    ChainTypeRouter,
    ChainTypeEvm,
    ChainTypeCosmos,
    ChainTypePolkadot,
    ChainTypeSolana,
    ChainTypeNear,
    ChainTypeTron,
    ChainTypeStarknet,
    ChainTypeBitcoin,
    ChainTypeSui,
    ChainTypeAlephZero,
}

impl ChainType {
    pub fn get_chain_code(&self) -> u64 {
        match self {
            ChainType::ChainTypeNone => 0,
            ChainType::ChainTypeRouter => 1,
            ChainType::ChainTypeEvm => 2,
            ChainType::ChainTypeCosmos => 3,
            ChainType::ChainTypePolkadot => 4,
            ChainType::ChainTypeSolana => 5,
            ChainType::ChainTypeNear => 6,
            ChainType::ChainTypeTron => 7,
            ChainType::ChainTypeStarknet => 8,
            ChainType::ChainTypeBitcoin => 9,
            ChainType::ChainTypeSui => 10,
            ChainType::ChainTypeAlephZero => 11,
        }
    }
}

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
pub enum AckType {
    NoAck,
    AckOnSuccess,
    AckOnError,
    AckOnBoth,
}

impl AckType {
    pub fn get_ack_code(&self) -> u8 {
        match self {
            AckType::NoAck => 0,
            AckType::AckOnSuccess => 1,
            AckType::AckOnError => 2,
            AckType::AckOnBoth => 3,
        }
    }

    pub fn get_ack_type(ack_type: u64) -> StdResult<AckType> {
        match ack_type {
            0 => Ok(AckType::NoAck),
            1 => Ok(AckType::AckOnSuccess),
            2 => Ok(AckType::AckOnError),
            3 => Ok(AckType::AckOnBoth),
            _ => StdResult::Err(StdError::not_found("Invalid AckType")),
        }
    }
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct CrosschainRequestResponse {
    pub request_identifier: u64,
    pub fee_deducted: Coin,
}

pub const INBOUND_OUTBOUND_MAPPING_EVENT_NAME: &str = "inbound_outbound_mapping_event";

pub const NATIVE_DENOM: &str = "route";

pub const EVM_ADDRESS_LENGTH: usize = 20;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)]
#[serde(rename_all = "snake_case")]
pub struct GasPriceResponse {
    pub gas_price: u64,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Default)]
#[serde(rename_all = "snake_case")]
pub struct TokenPriceResponse {
    pub token_price: Uint128,
    pub token_decimal: u64,
}