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,
}