near_api_types/
account.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use serde::{Deserialize, Serialize};
3
4use crate::{AccountId, CryptoHash, NearToken, StorageUsage, errors::DataConversionError};
5
6#[derive(
7    Serialize, Deserialize, Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq, Eq, Default,
8)]
9pub enum ContractState {
10    GlobalHash(CryptoHash),
11    GlobalAccountId(AccountId),
12    LocalHash(CryptoHash),
13    #[default]
14    None,
15}
16
17impl ContractState {
18    pub const fn from_global_contract_hash(hash: CryptoHash) -> Self {
19        Self::GlobalHash(hash)
20    }
21
22    pub const fn from_local_hash(hash: CryptoHash) -> Self {
23        Self::LocalHash(hash)
24    }
25}
26
27impl From<AccountId> for ContractState {
28    fn from(value: AccountId) -> Self {
29        Self::GlobalAccountId(value)
30    }
31}
32
33#[derive(Serialize, Deserialize, Debug, Clone, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
34pub struct Account {
35    pub amount: NearToken,
36    pub contract_state: ContractState,
37    pub locked: NearToken,
38    pub storage_usage: StorageUsage,
39}
40
41impl TryFrom<near_openapi_types::AccountView> for Account {
42    type Error = DataConversionError;
43
44    fn try_from(value: near_openapi_types::AccountView) -> Result<Self, Self::Error> {
45        let near_openapi_types::AccountView {
46            amount,
47            code_hash,
48            global_contract_account_id,
49            global_contract_hash,
50            locked,
51            storage_paid_at: _, // Intentionally ignoring this field. See (https://github.com/near/nearcore/issues/2271)
52            storage_usage,
53        } = value;
54
55        let code_hash = CryptoHash::try_from(code_hash)?;
56
57        let contract_state = match (code_hash, global_contract_account_id, global_contract_hash) {
58            (_, _, Some(hash)) => ContractState::from_global_contract_hash(hash.try_into()?),
59            (_, Some(account_id), _) => account_id.into(),
60            (hash, _, _) if hash == CryptoHash::default() => ContractState::None,
61            (hash, _, _) => ContractState::from_local_hash(hash),
62        };
63
64        Ok(Self {
65            amount: NearToken::from_yoctonear(amount.parse::<u128>()?),
66            contract_state,
67            locked: NearToken::from_yoctonear(locked.parse::<u128>()?),
68            storage_usage,
69        })
70    }
71}