use crate::address::Address;
use crate::error::CosmosGrpcError;
use bytes::BytesMut;
use cosmos_sdk_proto::cosmos::auth::v1beta1::{BaseAccount as ProtoBaseAccount, ModuleAccount};
use cosmos_sdk_proto::cosmos::vesting::v1beta1::{
ContinuousVestingAccount, DelayedVestingAccount, PeriodicVestingAccount, PermanentLockedAccount,
};
use cosmos_sdk_proto::tendermint::types::Block;
use prost::Message;
use prost_types::Any;
#[derive(Debug, Clone)]
pub enum ChainStatus {
Moving { block_height: u64 },
Syncing,
WaitingToStart,
}
#[derive(Debug, Clone)]
pub enum LatestBlock {
Latest { block: Block },
Syncing { block: Block },
WaitingToStart,
}
#[derive(Debug, Clone)]
pub enum AccountType {
ProtoBaseAccount(ProtoBaseAccount),
PeriodicVestingAccount(PeriodicVestingAccount),
ContinuousVestingAccount(ContinuousVestingAccount),
DelayedVestingAccount(DelayedVestingAccount),
ModuleAccount(ModuleAccount),
PermenantLockedAccount(PermanentLockedAccount),
}
impl AccountType {
pub fn get_base_account(&self) -> BaseAccount {
match self {
AccountType::ProtoBaseAccount(a) => a.get_base_account(),
AccountType::PeriodicVestingAccount(a) => a.get_base_account(),
AccountType::ContinuousVestingAccount(a) => a.get_base_account(),
AccountType::DelayedVestingAccount(a) => a.get_base_account(),
AccountType::ModuleAccount(a) => a.get_base_account(),
AccountType::PermenantLockedAccount(a) => a.get_base_account(),
}
}
pub fn decode_from_any(value: prost_types::Any) -> Result<Self, CosmosGrpcError> {
let mut buf = BytesMut::with_capacity(value.value.len());
buf.extend_from_slice(&value.value);
match (
ProtoBaseAccount::decode(buf.clone()),
ContinuousVestingAccount::decode(buf.clone()),
PeriodicVestingAccount::decode(buf.clone()),
DelayedVestingAccount::decode(buf.clone()),
ModuleAccount::decode(buf.clone()),
PermanentLockedAccount::decode(buf.clone()),
) {
(Ok(d), _, _, _, _, _) => Ok(AccountType::ProtoBaseAccount(d)),
(_, Ok(c), Ok(p), _, _, _) => {
if value.type_url.contains("Continuous") {
Ok(AccountType::ContinuousVestingAccount(c))
} else {
Ok(AccountType::PeriodicVestingAccount(p))
}
}
(_, Ok(d), _, _, _, _) => Ok(AccountType::ContinuousVestingAccount(d)),
(_, _, Ok(d), _, _, _) => Ok(AccountType::PeriodicVestingAccount(d)),
(_, _, _, Ok(d), _, _) => Ok(AccountType::DelayedVestingAccount(d)),
(_, _, _, _, Ok(d), _) => Ok(AccountType::ModuleAccount(d)),
(_, _, _, _, _, Ok(d)) => Ok(AccountType::PermenantLockedAccount(d)),
(Err(e), _, _, _, _, _) => Err(CosmosGrpcError::DecodeError { error: e }),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BaseAccount {
pub address: Address,
#[serde(skip_serializing, skip_deserializing)]
pub pubkey: Option<Any>,
pub account_number: u64,
pub sequence: u64,
}
impl From<ProtoBaseAccount> for BaseAccount {
fn from(value: ProtoBaseAccount) -> Self {
BaseAccount {
address: value.address.parse().unwrap(),
pubkey: value.pub_key,
account_number: value.account_number,
sequence: value.sequence,
}
}
}
pub trait CosmosAccount {
fn get_base_account(&self) -> BaseAccount;
}
impl CosmosAccount for BaseAccount {
fn get_base_account(&self) -> BaseAccount {
self.clone()
}
}
impl CosmosAccount for ProtoBaseAccount {
fn get_base_account(&self) -> BaseAccount {
self.clone().into()
}
}
impl CosmosAccount for ContinuousVestingAccount {
fn get_base_account(&self) -> BaseAccount {
self.base_vesting_account
.clone()
.unwrap()
.base_account
.unwrap()
.into()
}
}
impl CosmosAccount for DelayedVestingAccount {
fn get_base_account(&self) -> BaseAccount {
self.base_vesting_account
.clone()
.unwrap()
.base_account
.unwrap()
.into()
}
}
impl CosmosAccount for PeriodicVestingAccount {
fn get_base_account(&self) -> BaseAccount {
self.base_vesting_account
.clone()
.unwrap()
.base_account
.unwrap()
.into()
}
}
impl CosmosAccount for ModuleAccount {
fn get_base_account(&self) -> BaseAccount {
self.base_account.clone().unwrap().into()
}
}
impl CosmosAccount for PermanentLockedAccount {
fn get_base_account(&self) -> BaseAccount {
self.base_vesting_account
.clone()
.unwrap()
.base_account
.unwrap()
.into()
}
}
#[derive(Debug, Clone)]
pub struct BlockParams {
pub max_bytes: u64,
pub max_gas: Option<u64>,
}
#[cfg(test)]
mod tests {}