use serde::{Serialize, Deserialize};
use crate::schemas::data_api::{PreviousAssetSymbol, AssetAlternativeId, AssetIndustry, SpecialAddress};


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreSupportedPlatforms {
    #[serde(rename = "BLOCKCHAIN")]
    /// This is linked to the asset representing a specific chain.
    pub blockchain: Option<String>,
    #[serde(rename = "BRIDGE_OPERATOR")]
    pub bridge_oprator: Option<String>,
    #[serde(rename = "TOKEN_STANDARD")]
    /// This is linked to the Blockchain field and it is one of the SUPPORTED_STANDARDS available on that platform.
    pub token_standard: Option<String>,
    #[serde(rename = "SMART_CONTRACT_ADDRESS")]
    /// Contract/smart contract/token address where this asset is stored / interacted with on the specific blockchain platform.
    pub smart_contract_address: Option<String>,
    #[serde(rename = "EXPLORER_URL")]
    /// The URL for the token explorer website or tool.
    pub explorer_url: Option<String>,
    #[serde(rename = "DECIMALS")]
    /// The number of decimal points on the specific blockchain platform for this token.
    pub decimals: Option<i32>,
    #[serde(rename = "IS_ASSET_ISSUER")]
    pub is_asset_issuer: Option<bool>,
    #[serde(rename = "TRADING_AS")]
    /// The symbol/ticker this asset trades under on the specific blockchain platform.
    pub trading_as: Option<String>,
    #[serde(rename = "LAUNCH_DATE")]
    /// The data the smart contract on the supported platform was deployed or when the token was added.
    pub launch_date: Option<i64>,
}


// On-Chain Core: ETH Blocks


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHTrace {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "ID")]
    /// This is a unique identifier generated by combining the root trace type + transaction hash + trace addresses if available.
    pub id: String,
    #[serde(rename = "TRACE_TYPE")]
    /// The type of trace being recorded. It could be either "call", "reward", "suicide", "create", etc. depending on the type of action being traced.
    pub trace_type: Option<String>,
    #[serde(rename = "ADDRESS")]
    /// This represents the address associated with the trace. This could refer to the contract address, external user address, or any other relevant
    /// address in the context of the blockchain transaction.
    pub address: Option<Vec<i32>>,
    #[serde(rename = "ACTION_FROM")]
    /// This specifies the sender's address initiating the action.
    pub action_from: Option<String>,
    #[serde(rename = "ACTION_CALL_TYPE")]
    /// The type of call made, such as "call", "delegate call", or "static call". This is relevant when one contract invokes another.
    pub action_call_type: Option<String>,
    #[serde(rename = "ACTION_GAS")]
    /// The gas cost of executing the action. Gas is a measure of computational effort required for executing transactions and contract calls
    /// on the blockchain network.
    pub action_gas: Option<String>,
    #[serde(rename = "ACTION_INIT")]
    /// This is the bytecode that is executed to initialize the contract and determine its final code stored on the blockchain.
    pub action_init: Option<String>,
    #[serde(rename = "ACTION_INPUT")]
    /// The input data for the action (encoded in hexadecimal). For contract calls, this data includes function signatures and parameters.
    pub action_input: Option<String>,
    #[serde(rename = "ACTION_TO")]
    /// This specifies the recipient's address receiving the action, which could be a contract or an external address.
    pub action_to: Option<String>,
    #[serde(rename = "ACTION_VALUE")]
    /// The value or amount of cryptocurrency involved in the action. This is particularly important for actions like transactions
    /// where cryptocurrency is transferred.
    pub action_value: Option<String>,
    #[serde(rename = "ACTION_AUTHOR")]
    /// This specifies the sender's address that initiated or triggered a specific action within a transaction.
    /// It identifies the entity or account responsible for the action, such as a user or a smart contract.
    pub action_author: Option<String>,
    #[serde(rename = "ACTION_REWARD_TYPE")]
    /// The type of reward associated with the action, which might include mining rewards, staking rewards, or other types of incentives.
    pub action_reward_type: Option<String>,
    #[serde(rename = "ACTION_ADDRESS")]
    /// This is the contract whose code and storage are being removed from the blockchain.
    pub action_address: Option<String>,
    #[serde(rename = "ACTION_REFUND_ADDRESS")]
    /// This is usually an external account or another contract that the remaining Ether is sent to.
    pub action_refund_address: Option<String>,
    #[serde(rename = "ACTION_BALANCE")]
    /// This amount will be transferred to the ACTION_REFUND_ADDRESS. It's typically represented in wei (the smallest unit of Ether).
    pub action_balance: Option<String>,
    #[serde(rename = "RESULT_ADDRESS")]
    /// The address where the new contract is deployed.
    pub result_address: Option<String>,
    #[serde(rename = "RESULT_CODE")]
    /// This is the actual code that will be stored and executed on the blockchain, distinct from the init code that was used to generate it.
    pub result_code: Option<String>,
    #[serde(rename = "RESULT_GAS_USED")]
    /// The amount of gas actually consumed by the action during execution. This can be compared with the initial gas estimate to measure efficiency.
    pub result_gas_used: Option<String>,
    #[serde(rename = "RESULT_OUTPUT")]
    /// he output data produced by the action (encoded in hexadecimal), often used for reading the results of a contract call.
    pub result_output: Option<String>,
    #[serde(rename = "SUBTRACES")]
    /// Indicates the number of subtraces created as a result of the action. Subtraces are typically generated when a complex transaction
    /// or contract call triggers multiple internal calls.
    pub subtraces: Option<i32>,
    #[serde(rename = "ERROR")]
    /// Records any errors encountered during the execution of the action, providing information about the nature of the error.
    /// Example: *Reverted* or *invalid opcode*.
    pub error: Option<String>,
    #[serde(rename = "STATUS")]
    /// The overall status of the trace. Common values include "1" which means success and "0" which means failure,
    /// indicating whether the action was executed without errors.
    pub status: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHMetadata {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "NUMBER")]
    /// The sequential order of the block within the blockchain. Each block's number is one greater than the number of the previous block.
    pub number: i64,
    #[serde(rename = "TIMESTAMP")]
    /// The exact time when the block was mined. It's a crucial piece of information for tracking the chronological order of blocks.
    pub timestamp: i64,
    #[serde(rename = "HASH")]
    /// The unique identifier for the block, generated using cryptographic algorithms.
    /// It represents the content of the block and is used for verification and linking blocks together.
    pub hash: String,
    #[serde(rename = "PARENT_HASH")]
    /// The hash of the previous block in the blockchain. It establishes the chronological link between blocks.
    pub parent_hash: String,
    #[serde(rename = "NONCE")]
    /// This is a random number used in the process of mining. It's combined with other block data to create a hash that meets specific mining criteria.
    pub nonce: String,
    #[serde(rename = "SHA3_UNCLES")]
    /// This stores the hash of the block's uncles, which are valid blocks that were not included in the main blockchain but can provide additional rewards to miners.
    pub sha3_uncles: String,
    #[serde(rename = "LOGS_BLOOM")]
    /// This is a data structure that represents the presence of log entries in the block's transactions.
    /// It's used for efficient retrieval of logs associated with transactions.
    pub logs_bloom: String,
    #[serde(rename = "TRANSACTIONS_ROOT")]
    /// The hash of the root node of the Merkle tree that organizes the transactions in the block. It enables quick verification of included transactions.
    pub transaction_root: String,
    #[serde(rename = "STATE_ROOT")]
    /// This hash represents the state of the blockchain after all transactions in the block have been executed.
    /// It's used to ensure the consistency of the blockchain's state.
    pub state_root: String,
    #[serde(rename = "MERKLE_ROOT")]
    /// The Merkle root hash, which summarizes all the transactions included in the block. It ensures the integrity of the transactions.
    pub merkle_root: Option<String>,
    #[serde(rename = "RECEIPTS_ROOT")]
    /// This is similar to the transactions root, the receipts root hash is the root of a Merkle tree, but it stores the receipts of transactions,
    /// including information about their success or failure.
    pub receipts_root: String,
    #[serde(rename = "MINER")]
    /// This specifies the address of the miner who successfully mined the block. This miner is rewarded with cryptocurrency for their effort.
    pub miner: String,
    #[serde(rename = "MIX_HASH")]
    /// This is a 256-bit hash value. It's essentially a part of the proof-of-work mechanism used in Ethereum to secure the blockchain.
    /// This hash is derived from the mixing of various components of the block, including the nonce, timestamp, previous block's hash, and more.
    pub mix_hash: String,
    #[serde(rename = "DIFFICULTY")]
    /// This indicates how hard it was to mine the block. It's adjusted based on the overall network's hash rate to maintain a consistent block generation rate.
    pub difficulty: String,
    #[serde(rename = "TOTAL_DIFFICULTY")]
    /// This field accumulates the difficulty values of all previous blocks, providing a measure of the blockchain's security.
    pub total_difficulty: String,
    #[serde(rename = "CHAIN_WORK")]
    /// The total cumulative amount of work in the blockchain up to and including this block. It's a measure of the blockchain's security.
    pub chain_work: Option<String>,
    #[serde(rename = "SIZE")]
    /// The size of the block in bytes. It includes all the data and metadata within the block.
    pub size: i64,
    #[serde(rename = "WEIGHT")]
    /// A metric for the block's size that considers both the non-SegWit and SegWit data, used to ensure blocks remain within the maximum block weight.
    pub weight: Option<i64>,
    #[serde(rename = "BLOCK_TIME")]
    /// The time taken in seconds between mining the previous and current block. It's an important metric for understanding the network's performance and stability.
    pub block_time: f64,
    #[serde(rename = "MEDIAN_TIME")]
    /// The median time of the last 11 blocks. It's used to ensure the network's time consistency.
    pub median_time: Option<f64>,
    #[serde(rename = "BLOB_GAS_USED")]
    pub blob_gas_used: String,
    #[serde(rename = "EXCESS_BLOB_GAS")]
    pub excess_blob_gas: String,
    #[serde(rename = "EXTRA_DATA")]
    /// This allows miners to include arbitrary information in the block. It's often used to add contextual information or messages.
    pub extra_data: String,
    #[serde(rename = "GAS_LIMIT")]
    /// The maximum amount of computational work a block can contain. Each transaction consumes a specific amount of gas, and this limit prevents abuse of the network's resources.
    pub gas_limit: String,
    #[serde(rename = "GAS_USED")]
    /// The total amount of gas consumed by all transactions in the block. It helps in understanding the efficiency of transactions.
    pub gas_used: String,
    #[serde(rename = "TRANSACTION_COUNT")]
    /// This indicates how many transactions are included in the block.
    pub transaction_count: i64,
    #[serde(rename = "BASE_FEE_PER_GAS")]
    /// The base fee for each unit of gas in transactions. It's part of Ethereum's fee market mechanism.
    pub base_fee_per_gas: String,
    #[serde(rename = "WITHDRAWALS_ROOT")]
    /// The hash value that represents a data structure containing information about the withdrawals that occurred in the block.
    pub withdrawals_root: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// This causes a transaction to warm (i.e. pre-cache) another addresses state and the specified storage keys, Available on EIP-2930 transactions.
pub struct OCCoreETHTransactionAccessList {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: Option<String>,
    #[serde(rename = "ADDRESS")]
    /// Internal mapped Block Transaction Access address state.
    pub address: Option<String>,
    #[serde(rename = "Storage_KEYS")]
    /// An array of storage keys associated with the address mentioned above. Storage keys are unique identifiers used to access data within
    /// a smart contract's storage on the blockchain. Smart contracts often store data in a key-value format, where the storage keys are used
    /// to retrieve specific values.
    pub storage_keys: Option<Vec<String>>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// The current transaction blobs, null when there are no blobs attached to the transaction.
pub struct OCCoreETHTransactionBlob {
    #[serde(rename = "TYPE")]
    pub type_: Option<String>,
    #[serde(rename = "INDEX")]
    pub index: Option<i32>,
    #[serde(rename = "VERSIONED_HASH")]
    pub version_hash: Option<String>,
    #[serde(rename = "KZG_COMMITMENT")]
    pub kzg_commitment: Option<String>,
    #[serde(rename = "KZG_PROOF")]
    pub kzg_proof: Option<String>,
    #[serde(rename = "KZG_COMMITMENT_INCLUSION_PROOF")]
    pub kzg_commitment_inclusion_proof: Option<Vec<String>>,
    #[serde(rename = "SIZE")]
    pub size: Option<i32>,
    #[serde(rename = "DATA")]
    pub data: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// The chronological records of all activities such as transaction executions, contract interactions, errors, and changes that occur within a blockchain network.
pub struct OCCoreETHTransactionLog {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: Option<String>,
    #[serde(rename = "ADDRESS")]
    /// The address of the contract or account that generated the log entry.
    /// It serves as an identifier for the source of the event or action that triggered the log.
    pub address: Option<String>,
    #[serde(rename = "INDEX")]
    /// The position of the log entry within the sequence of logs generated by a transaction.
    /// It's usually an incremental integer starting from 0 for the first log in a transaction.
    /// This field helps in distinguishing and organizing logs generated during a transaction.
    pub index: Option<i32>,
    #[serde(rename = "DATA")]
    /// This contains the arbitrary data associated with the log entry.
    /// This data can vary depending on the specific smart contract and event that generated the log.
    /// It might include relevant information about the state change or action represented by the log.
    pub data: Option<String>,
    #[serde(rename = "TOPICS")]
    /// An array of one or more indexed event topics. These topics are hash values of event signatures or indexed arguments.
    /// They provide a way to filter and search for specific types of events within the logs efficiently.
    pub topics: Option<Vec<String>>,
    #[serde(rename = "REMOVED")]
    /// A a boolean indicator that signals whether the log entry has been removed or undone due to a chain reorganization or a consensus rule change.
    /// It helps applications differentiate between active and reverted logs. It is "true" if log was removed, otherwise false.
    pub removed: Option<bool>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHTransaction {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "HASH")]
    /// Transaction internal mapped hash. (For BTC transactions without SegWit data, this is the same as the txid. For SegWit transactions,
    /// this represents the hash of the transaction including the witness data).
    pub hash: String,
    #[serde(rename = "TRANSACTION_TYPE")]
    /// The EIP-2718 type of this transaction envelope.
    pub transaction_type: i32,
    #[serde(rename = "NONCE")]
    /// The number of transactions made by the sender prior to this one encoded as hexadecimal.
    /// It prevents duplicate transactions and maintains order in the blockchain.
    pub nonce: i64,
    #[serde(rename = "INDEX")]
    /// The position of the transaction within the block. Helps in identifying the order of transactions in the block.
    pub index: i32,
    #[serde(rename = "FROM_ADDRESS")]
    /// The address of the sender.
    pub from_address: String,
    #[serde(rename = "TO_ADDRESS")]
    /// The address of the recipient. Null when its a contract creation transaction.
    pub to_address: String,
    #[serde(rename = "VALUE")]
    /// The amount of cryptocurrency being transferred from the sender to the recipient.
    pub value: String,
    #[serde(rename = "GAS")]
    /// The amount of computational work a transaction requires to be executed.
    /// This is used to determine the fees paid by the sender to incentivize miners to include the transaction in a block.
    pub gas: String,
    #[serde(rename = "LOGS_BLOOM")]
    pub logs_bloom: Option<String>,
    #[serde(rename = "L1_GAS_USED")]
    /// The amount of gas used specifically by the current transaction.
    pub l1_gas_used: Option<i32>,
    #[serde(rename = "L1_FEE")]
    pub l1_fee: Option<i32>,
    #[serde(rename = "L1_GAS_PRICE")]
    pub l1_gas_price: Option<i32>,
    #[serde(rename = "DEPOSIT_NONCE")]
    pub deposit_nonce: Option<i64>,
    #[serde(rename = "DEPOSIT_RECEIPT_VERSION")]
    pub deposit_receipt_version: Option<i32>,
    #[serde(rename = "GAS_PRICE")]
    /// The price the sender is willing to pay for each unit of gas. Together with the gas limit, it determines the total fee for the transaction.
    pub gas_price: String,
    #[serde(rename = "INPUT")]
    /// The data associated with the transaction, often used in smart contract interactions. It can contain parameters and instructions for contract execution.
    pub input: String,
    #[serde(rename = "RECEIPT_BLOB_GAS_PRICE")]
    /// The total gas price of the transaction blobs.
    pub receipt_blob_gas_price: Option<String>,
    #[serde(rename = "RECEIPT_BLOB_GAS_USED")]
    /// The total amount of gas used by the transaction blobs.
    pub receipt_blob_gas_used: Option<String>,
    #[serde(rename = "RECEIPT_CUMULATIVE_GAS_USED")]
    /// The total amount of gas used by the transaction and all preceding transactions within the same block.
    pub receipt_cumulative_gas_used: Option<String>,
    #[serde(rename = "RECEIPT_GAS_USED")]
    /// The amount of gas used specifically by the current transaction.
    pub receipt_gas_used: Option<String>,
    #[serde(rename = "RECEIPT_CONTACT_ADDRESS")]
    /// This is the address created when a contract is deployed. The *TO* field should be null in this case.
    pub receipt_contact_address: Option<String>,
    #[serde(rename = "RECEIPT_ROOT")]
    /// Only transactions included in blocks before the Byzantium Hard Fork have this field, as it was replaced by the *STATUS* field.
    pub receipt_root: Option<String>,
    #[serde(rename = "RECEIPT_STATUS")]
    /// The status of a transaction is "1" if successful or "0" if it was a failure or reverted.
    /// Only transactions included in blocks post-Byzantium Hard Fork have this field.
    pub receipt_status: i32,
    #[serde(rename = "MAX_FEE_PER_GAS")]
    /// The maximum fee per gas unit that the sender is willing to pay for a transaction to be included promptly in a block.
    pub max_fee_per_gas: Option<String>,
    #[serde(rename = "MAX_PRIORITY_FEE_PER_GAS")]
    /// The maximum fee per gas unit that the sender is willing to pay for higher priority processing of the transaction.
    pub max_priority_fee_per_gas: Option<String>,
    #[serde(rename = "MAX_FEE_PER_BLOB_GAS")]
    /// The maximum fee per gas unit that the sender is willing to pay for higher priority processing of the transaction.
    pub max_fee_per_blob_gas: Option<String>,
    #[serde(rename = "RECEIPT_EFFECTIVE_GAS_PRICE")]
    /// The total base charge plus tip paid for each unit of gas.
    pub receipt_effective_gas_price: Option<String>,
    #[serde(rename = "ACCESS_LIST")]
    /// This causes a transaction to warm (i.e. pre-cache) another addresses state and the specified storage keys, Available on EIP-2930 transactions.
    pub access_list: Option<Vec<OCCoreETHTransactionAccessList>>,
    #[serde(rename = "BLOBS")]
    /// The current transaction blobs, null when there are no blobs attached to the transaction.
    pub blobs: Option<Vec<OCCoreETHTransactionBlob>>,
    #[serde(rename = "ECDSA_V")]
    /// This is part of ECDSA (Elliptic Curve Digital Signature Algorithm) signature.
    /// This value helps to recover which public key was used to sign the transaction. Calculated as (CHAIN_ID * 2 + 35) or (CHAIN_ID * 2 + 36).
    pub ecdsa_v: Option<i32>,
    #[serde(rename = "ECDSA_R")]
    /// This is part of ECDSA (Elliptic Curve Digital Signature Algorithm) signature. It is derived from the private key and the data to be signed.
    pub ecdsa_r: Option<String>,
    #[serde(rename = "ECDSA_S")]
    /// This is part of ECDSA (Elliptic Curve Digital Signature Algorithm) signature. It is derived from the private key and the data to be signed.
    pub ecdsa_s: Option<String>,
    #[serde(rename = "Y_PARITY")]
    /// This is a recent addition from July 2023 and could be used instead of the ECDSA_V. ECDSA_V would be used for backward compatibility.
    pub y_parity: Option<String>,
    #[serde(rename = "TRACES")]
    /// The detailed records of the steps and interactions that occured during the execution of this transaction.
    pub traces: Option<Vec<OCCoreETHTrace>>,
    #[serde(rename = "LOGS")]
    /// The chronological records of all activities such as transaction executions, contract interactions,
    /// errors, and changes that occur within a blockchain network.
    pub logs: Option<Vec<OCCoreETHTransactionLog>>,
    #[serde(rename = "HEX")]
    /// The raw hexadecimal representation of the entire transaction data.
    pub hex: Option<String>,
    #[serde(rename = "SOURCE_HASH")]
    /// Transaction source hash.
    pub source_hash: Option<String>,
    #[serde(rename = "MINT")]
    pub mint: Option<i32>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHUncle {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHWithdrawal {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "INDEX")]
    /// The unique identifier or index associated with a blockchain withdrawal transaction.
    /// It helps in keeping track of individual withdrawals and organizing them in a sequential or ordered manner.
    pub index: i32,
    #[serde(rename = "VALIDATOR_INDEX")]
    /// The identifier of the validator or node that approved or validated the withdrawal transaction.
    /// In proof-of-stake or similar consensus mechanisms, validators play a crucial role in ensuring the legitimacy of transactions,
    /// and this field ties a withdrawal to a specific validator.
    pub validator_index: i32,
    #[serde(rename = "ADDRESS")]
    /// The destination address to which the withdrawn cryptocurrency is being sent. This address is usually a cryptographic
    /// public key or a combination of alphanumeric characters that uniquely identifies the recipient's wallet or account on the blockchain.
    pub address: String,
    #[serde(rename = "AMOUNT")]
    /// The quantity of cryptocurrency being withdrawn in the transaction. It specifies the numerical value of the cryptocurrency units
    /// being transferred from the withdrawal source to the recipient's address.
    pub amount: String,
    #[serde(rename = "UNIT")]
    /// The type of cryptocurrency being withdrawn. It could be a symbol or code that represents the specific cryptocurrency asset
    /// being transferred, such as "BTC" for Bitcoin or "GWEI" for Ethereum.
    pub unit: String,
}

/// ON-Chain Core: ETH Blocks
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreETHBlock {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "ASSET_ID")]
    /// The unique identifier for the asset the field is associated to.
    pub asset_id: i32,
    #[serde(rename = "SYMBOL")]
    /// Internal mapped symbol for a specific asset.
    pub symbol: String,
    #[serde(rename = "PROVIDER_KEY")]
    /// Internal mapped Blockchain provider key for a specific asset.
    pub provider_key: String,
    #[serde(rename = "CHAIN_ID")]
    /// This is the Id of the blockchain.
    pub chain_id: i32,
    #[serde(rename = "IS_PART_OF_REORG")]
    /// Is this block part of a reorg? this would happen when we get block reorgs due to a longer chain being published by some of the miners.
    pub is_part_of_reorg: bool,
    #[serde(rename = "NUMBER")]
    /// The current block number.
    pub number: i64,
    #[serde(rename = "TIMESTAMP")]
    /// The current block timestamp.
    pub timestamp: i64,
    #[serde(rename = "RECEIVED_TIMESTAMP")]
    /// The current block received timestamp.
    pub received_timestamp: i64,
    #[serde(rename = "METADATA")]
    /// The current block full metadata.
    pub metadata: OCCoreETHMetadata,
    #[serde(rename = "TRANSACTIONS")]
    /// The current block transactions.
    pub transactions: Option<Vec<OCCoreETHTransaction>>,
    #[serde(rename = "ORPHAN_TRACES")]
    /// Block traces not linked to a transaction.
    pub orphan_traces: Option<Vec<OCCoreETHTrace>>,
    #[serde(rename = "UNCLES")]
    /// The current block uncles.
    pub uncles: Option<Vec<OCCoreETHUncle>>,
    #[serde(rename = "WITHDRAWALS")]
    /// The current block withdrawal.
    pub withdrawals: Option<Vec<OCCoreETHWithdrawal>>,
}


// On-Chain Core: Assets Summary By Chain


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ChainAssetSummary {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "ID")]
    /// The unique identifier for the asset entry.
    pub id: i32,
    #[serde(rename = "SYMBOL")]
    /// Internal mapped symbol for a specific asset.
    pub symbol: String,
    #[serde(rename = "ASSET_TYPE")]
    /// he asset class/type.
    pub asset_type: String,
    #[serde(rename = "NAME")]
    /// The full name of the asset, e.g. Bitcoin.
    pub name: String,
    #[serde(rename = "LOGO_URL")]
    /// The image that appears when you see this asset.
    pub logo_url: String,
    #[serde(rename = "LAUNCH_DATE")]
    /// The launch date of the asset is indicated as (yyyy-mm-dd). However, if the asset was initially established as a token before being integrated into
    /// a blockchain, the launch date is reset to the creation of the first block when the blockchain is launched for the token.
    pub launch_date: Option<i64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SupportedAsset {
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "ID")]
    /// The unique identifier for the asset entry.
    pub id: i32,
    #[serde(rename = "SYMBOL")]
    /// Internal mapped symbol for a specific asset.
    pub symbol: String,
    #[serde(rename = "ASSET_TYPE")]
    /// he asset class/type.
    pub asset_type: String,
    #[serde(rename = "NAME")]
    /// The full name of the asset, e.g. Bitcoin.
    pub name: String,
    #[serde(rename = "LOGO_URL")]
    /// The image that appears when you see this asset.
    pub logo_url: Option<String>,
    #[serde(rename = "LAUNCH_DATE")]
    /// The launch date of the asset is indicated as (yyyy-mm-dd). However, if the asset was initially established as a token before being integrated into
    /// a blockchain, the launch date is reset to the creation of the first block when the blockchain is launched for the token.
    pub launch_date: Option<i64>,
    #[serde(rename = "FILTERED_SUPPORTED_PLATFORMS")]
    pub filtered_supported_platforms: Option<Vec<OCCoreSupportedPlatforms>>,
}

/// On-Chain Core: Assets Summary By Chain
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreAssetByChain {
    #[serde(rename = "CHAIN_ASSET_SUMMARY")]
    /// The statistics of the current page.
    pub chain_asset_summary: ChainAssetSummary,
    #[serde(rename = "ASSETS_SUPPORTED")]
    /// The list of summary asset data.
    pub assets_supported: Vec<SupportedAsset>,
}


// On-Chain Core: Asset by Address


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreSecurityMetric {
    #[serde(rename = "NAME")]
    pub name: String,
    #[serde(rename = "OVERALL_SCORE")]
    pub overall_score: f64,
    #[serde(rename = "OVERALL_RANK")]
    pub overall_rank: f64,
    #[serde(rename = "UPDATED_AT")]
    pub updated_at: i64,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// A detailed breakdown of reserves backing a stablecoin asset, covering various categories such as cash, cryptocurrency, bonds, and
    /// other investments for transparency.
pub struct OCCoreReservesBreakdown {
    #[serde(rename = "RESERVE_TYPE")]
    /// The type of asset used for reserve collateralization, such as cash, crypto, or bonds.
    pub reserve_type: String,
    #[serde(rename = "HOLDING_ADDRESSES")]
    /// An array of objects containing the blockchain chain and the holding address (wallet or smart contract) for proof of reserves.
    pub holding_addresses: String,
    #[serde(rename = "PERCENTAGE")]
    /// The percentage of the total reserves allocated to this particular reserve type.
    pub percentage: f64,
    #[serde(rename = "DESCRIPTION")]
    /// A brief description for the reserves, clarifying the nature of the reserve type.
    pub description: String,
    #[serde(rename = "COMMENTS")]
    /// Any additional internal comments or information about the reserves.
    pub comments: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// Documents that might be relevant to the asset, they should all be .PDFs.
pub struct OCCoreDocumentURLs {
    #[serde(rename = "TYPE")]
    pub type_: String,
    #[serde(rename = "VERSION")]
    pub version: i32,
    #[serde(rename = "URL")]
    pub url: String,
    #[serde(rename = "COMMENT")]
    pub comment: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// Denotes the convesion asset ID, SYMBOL and ASSET_TYPE.
pub struct OCCorePriceConversionAsset {
    #[serde(rename = "ID")]
    /// The unique identifier for the asset entry.
    pub id: i32,
    #[serde(rename = "SYMBOL")]
    /// Internal mapped symbol for a specific asset.
    pub symbol: String,
    #[serde(rename = "ASSET_TYPE")]
    /// The type of the asset (FIAT, BLOCKCHAIN, TOKEN, etc.).
    pub asset_type: String,
}

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
/// Indicates the asset's position in our global asset ranking. There are multiple ranks, each is determined by at least one factor,
/// such as asset launch date, market cap, trading volume, etc...
pub struct OCCoreToplistRank {
    #[serde(rename = "CREATED_ON")]
    /// Rank based on CREATED_ON sorted ASC from earliest created to most recent one.
    pub created_on: i64,
    #[serde(rename = "LAUNCH_DATE")]
    /// Rank based on LAUNCH_DATE sorted ASC from earliest launched to most recently launched one.
    pub launch_date: i64,
    #[serde(rename = "PRICE_USD")]
    /// Rank based on PRICE_USD sorted DESC from most expensive asset to cheapest one.
    pub price_usd: Option<f64>,
    #[serde(rename = "CIRCULATING_MKT_CAP_USD")]
    /// Rank based on CIRCULATING_MKT_CAP_USD sorted DESC from highest circulating market cap to lowest.
    pub circulating_mkt_cap_usd: Option<f64>,
    #[serde(rename = "TOTAL_MKT_CAP_USD")]
    /// Rank based on TOTAL_MKT_CAP_USD sorted DESC from highest total market cap to lowest.
    pub total_mkt_cap_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_DIRECT_USD sorted DESC from highest quote
    /// volume accross top tier markets that trade directly to USD to lowest.
    pub spot_moving_24_hour_quote_volume_top_tier_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_QUOTE_VOLUME_DIRECT_USD sorted DESC from highest volume accross all markets that trade directly to USD to lowest.
    pub spot_moving_24_hour_quote_volume_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD sorted DESC from highest quote volume accross top tier markets to lowest.
    pub spot_moving_24_hour_quote_volume_top_tier_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD sorted DESC from highest quote volume accross all markets to lowest.
    pub spot_moving_24_hour_quote_volume_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_CHANGE_USD sorted DESC from highest change accross all markets to lowest.
    pub spot_moving_24_hour_change_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD")]
    /// Rank based on SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD sorted DESC from highest percentage change accross all markets to lowest.
    pub spot_moving_24_hour_change_percentage_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD sorted DESC from highest quote volume accross top tier markets that
    /// trade directly to USD to lowest.
    pub spot_moving_7_day_quote_volume_top_tier_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_QUOTE_VOLUME_DIRECT_USD sorted DESC from highest volume accross all markets that trade directly to USD to lowest.
    pub spot_moving_7_day_quote_volume_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_USD sorted DESC from highest quote volume accross top tier markets to lowest.
    pub spot_moving_7_day_quote_volume_top_tier_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_QUOTE_VOLUME_USD sorted DESC from highest quote volume accross all markets to lowest.
    pub spot_moving_7_day_quote_volume_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_CHANGE_USD sorted DESC from highest change accross all markets to lowest.
    pub spot_moving_7_day_change_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_PERCENTAGE_USD")]
    /// Rank based on SPOT_MOVING_7_DAY_CHANGE_PERCENTAGE_USD sorted DESC from highest percentage change accross all markets to lowest.
    pub spot_moving_7_day_change_percentage_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD sorted DESC from highest quote volume accross top tier markets
    /// that trade directly to USD to lowest.
    pub spot_moving_30_day_quote_volume_top_tier_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_DIRECT_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_QUOTE_VOLUME_DIRECT_USD sorted DESC from highest volume accross all markets that trade directly to USD to lowest.
    pub spot_moving_30_day_quote_volume_direct_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_USD sorted DESC from highest quote volume accross top tier markets to lowest.
    pub spot_moving_30_day_quote_volume_top_tier_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_QUOTE_VOLUME_USD sorted DESC from highest quote volume accross all markets to lowest.
    pub spot_moving_30_day_quote_volume_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_CHANGE_USD sorted DESC from highest change accross all markets to lowest.
    pub spot_moving_30_day_change_usd: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_PERCENTAGE_USD")]
    /// Rank based on SPOT_MOVING_30_DAY_CHANGE_PERCENTAGE_USD sorted DESC from highest percentage change accross all markets to lowest.
    pub spot_moving_30_day_change_percentage_usd: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// Individuals that contains founders, whitepaper authors, investors, resechers, and other important people related to a project.
pub struct OCCoreProjectLeader {
    #[serde(rename = "LEADER_TYPE")]
    pub leader_type: String,
    #[serde(rename = "FULL_NAME")]
    pub fuill_name: String,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
/// Associated contact addresses for the team members, employees or affiliated contacts.
pub struct OCCoreContactDetails {
    #[serde(rename = "CONTACT_TYPE")]
    pub contact_type: String,
    #[serde(rename = "CONTACT_MEDIUM")]
    pub contact_medium: String,
    #[serde(rename = "FULL_NAME")]
    pub full_name: String,
    #[serde(rename = "ADDRESS")]
    /// The email / linkedin addres / twitter / other social media address.
    pub address: String,
    #[serde(rename = "COMMENTS")]
    pub comments: String,
}

/// On-Chain Core: Asset by Address
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreAssetByAddress {
    #[serde(rename = "ID")]
    /// The unique identifier for the asset entry.
    pub id: i32,
    #[serde(rename = "TYPE")]
    /// Type of the message.
    pub type_: String,
    #[serde(rename = "ID_LEGACY")]
    /// The legacy previous asset management system ID.
    pub id_legacy: i32,
    #[serde(rename = "ID_PARENT_ASSET")]
    /// This refers to the base, parent, or main asset to which a token is linked or pegged, signifying that the token acts as a representation of the parent asset.
    /// When a token loses its connection to a parent asset due to events such as hacks or the issuing entity's decision to not honor the peg—similar to how
    /// TerraUSD detached from its USD peg—the PARENT_ASSET_SYMBOL is removed because the token no longer serves as a true representation of the parent asset.
    /// In order to remove the parent we need clear communication from the company who is in charge of keeping the peg.
    /// We add add a plublic notice and the include the communication in the Other Document URLs.
    pub id_parent_asset: i32,
    #[serde(rename = "IS_ASSET_ISSUER")]
    /// This field identifies the original creator of the token. It provides essential information about the entity, individual or contract rules responsible for
    /// issuing the token initially and/or maintaining the supply. In the case of of bridged assets, this is the bridge operator and the parent will have
    /// its own issuer. You can go up the parent chain and figure out what counterparty risk you are exposed to when trading a specific asset.
    /// This clarification ensures that users can directly trace the origin of the token, understanding its issuance history and the primary issuer's credentials.
    pub id_asset_issuer: Option<i32>,
    #[serde(rename = "SYMBOL")]
    /// Internal mapped symbol for a specific asset.
    pub symbol: String,
    #[serde(rename = "URI")]
    /// The uri path that this asset will be found on / url-slug.
    pub uri: String,
    #[serde(rename = "ASSET_TYPE")]
    /// The asset class/type.
    pub asset_type: String,
    #[serde(rename = "ASSET_ISSUER_NAME")]
    /// This field identifies the original creator of the asset. It provides essential information about the entity, individual or contract rules responsible for
    /// issuing the asset initially and/or maintaining the supply. In the case of of bridged assets, this is the bridge operator and the parent will have its
    /// own issuer. You can go up the parent chain and figure out what counterparty risk you are exposed to when trading a specific asset.
    /// This clarification ensures that users can directly trace the origin of the asset, understanding its issuance history and the primary issuer's credentials.
    pub asset_issuer_name: Option<String>,
    #[serde(rename = "PARENT_ASSET_SYMBOL")]
    /// his refers to the base, parent, or main asset to which a token is linked or pegged, signifying that the token acts as a representation of the parent asset. 
    /// When a token loses its connection to a parent asset due to events such as hacks or the issuing entity's decision to not honor the peg—similar to how
    /// TerraUSD detached from its USD peg—the PARENT_ASSET_SYMBOL is removed because the token no longer serves as a true representation of the parent asset.
    /// In order to remove the parent we need clear communication from the company who is in charge of keeping the peg.
    /// We add add a plublic notice and the include the communication in the Other Document URLs.
    pub parent_asset_symbol: Option<String>,
    #[serde(rename = "ROOT_ASSET_ID")]
    /// Identifies the root asset in a chain of derived or related assets, essential for tracing asset lineage. Null if the asset does not have a parent.
    /// For example, the fiat USD (id: 5) would be the root asset for the tokens CUSDC (id: 1623) or USDCE (id: 1728).
    pub root_asset_id: i32,
    #[serde(rename = "ROOT_ASSET_SYMBOL")]
    /// The symbol of the root asset, facilitating recognition and correlation within asset hierarchies. Null if the asset does not have a parent.
    /// For example, the fiat USD (id: 5) would be the root asset for the tokens CUSDC (id: 1623) or USDCE (id: 1728).
    pub root_asset_symbol: String,
    #[serde(rename = "ROOT_ASSET_TYPE")]
    /// Specifies the fundamental category of the root asset, crucial for understanding the base or origin of an asset's classification.
    /// Null if the asset does not have a parent. For example, the fiat USD would be the root asset for tokens CUSDC or USDCE, and in this case,
    /// the ROOT_ASSET_TYPE would be fiat.
    pub root_asset_type: String,
    #[serde(rename = "CREATED_ON")]
    /// Asset internal creation unix ts in our system.
    pub created_on: i64,
    #[serde(rename = "UPDATED_ON")]
    /// Asset internal last updated unix ts in our system.
    pub updated_on: i64,
    #[serde(rename = "PUBLIC_NOTICE")]
    /// A public notice for this asset.
    pub public_notice: Option<String>,
    #[serde(rename = "NAME")]
    /// The full name of the asset, e.g. Bitcoin.
    pub name: String,
    #[serde(rename = "LOGO_URL")]
    /// The image that appears when you see this asset.
    pub logo_url: String,
    #[serde(rename = "LAUNCH_DATE")]
    /// The launch date of the asset is indicated as (yyyy-mm-dd). However, if the asset was initially established as a token before being integrated into
    /// a blockchain, the launch date is reset to the creation of the first block when the blockchain is launched for the token.
    pub launch_date: i64,
    #[serde(rename = "PERIOUS_ASSET_SYMBOLS")]
    /// A list of symbols that were previously associated with this asset.
    pub previous_asset_symbols: Option<Vec<PreviousAssetSymbol>>,
    #[serde(rename = "ASSET_ALTERNATIVE_IDS")]
    /// Alternative data platforms that also support this asset with their specific asset id.
    pub asset_laternative_ids: Option<Vec<AssetAlternativeId>>,
    #[serde(rename = "ASSET_DESCRIPTION_SNIPPET")]
    /// The shortest form description text only for this asset. This is a lot more limited than the summary. Generally this is a one or maximum two sentences.
    pub asset_description_snippet: Option<String>,
    #[serde(rename = "SUPPORTED_PLATFORMS")]
    /// When an asset (token, fiat, cryptocurrency, commodity) can be used on multiple blockchains, we refer to those blockchains as supported platforms.
    /// There are two types of assets that can be used on multiple blockchains: native tokens and bridged tokens.
    /// Native tokens are assets that are natively supported by a particular blockchain, while bridged tokens are assets that are "bridged" or "pegged"
    /// to another asset on a different blockchain.
    pub supported_platforms: Option<Vec<OCCoreSupportedPlatforms>>,
    #[serde(rename = "ASSET_SECURITY_METRICS")]
    pub asset_security_metrics: Option<Vec<OCCoreSecurityMetric>>,
    #[serde(rename = "SUPPLY_MAX")]
    /// The maximum number of asset parts (coins/tokens) that will ever be issued (supply_circulating + supply_burnt + supply_locked + all supply that
    /// has not been issued yet but is planned to be issued in the future). For assets (coins/tokens) that have infinite supply, we use -1.
    pub supply_max: f64,
    #[serde(rename = "SUPPLY_ISSUED")]
    /// The number of asset parts (coins/tokens) that have been issued so far. (supply_circulating + supply_locked + supply_burnt).
    pub supply_issued: Option<f64>,
    #[serde(rename = "SUPPLY_TOTAL")]
    /// The number of asset parts (coins/tokens) that have been issued so far excluding burnt tokens. (supply_circulating + supply_locked).
    pub supply_total: Option<f64>,
    #[serde(rename = "SUPPLY_CIRCULATING")]
    /// Also referred to as free float or public float. The number of asset parts (coins/tokens) that are available to be traded and it
    /// excludes burnt supply and locked supply.
    pub supply_circulating: Option<f64>,
    #[serde(rename = "SUPPLY_FUTURE")]
    /// The number of asset parts (coins/tokens) that are planned to be issued in the future. (supply_max - supply_issued).
    pub supply_future: f64,
    #[serde(rename = "SUPPLY_LOCKED")]
    /// The number of asset parts (coins/tokens) that are currently not transferable until certain conditions are met.
    /// Locked supply is generally held by team members, DAOs, foundations, bridges, stakers, liquidity pools, etc.
    pub supply_locked: Option<f64>,
    #[serde(rename = "SUPPY_BURNT")]
    /// The number of asset parts (coins/tokens) that have been sent to addresses/locations that are no longer accessible.
    /// They are permanently removed from the circulating supply on purpose, this does not include lost tokens sent to wallets that do not exist or
    // sent to wallets that users no longer have access to, the address of burnt tokens is determined by the project team.
    pub supply_burnt: Option<f64>,
    #[serde(rename = "SUPPLY_STAKED")]
    /// The current number of asset parts (coins/tokens) that are locked as part of PoS and PoS partial chains.
    pub supply_staked: Option<f64>,
    #[serde(rename = "BURN_ADDRESSES")]
    /// The list of addresses that are considered burn addresses for this asset.
    pub burn_addresses: Option<Vec<SpecialAddress>>,
    #[serde(rename = "LOCKED_ADDRESSES")]
    /// The list of addresses that are considered locked addresses for this asset.
    pub locked_addresses: Option<Vec<SpecialAddress>>,
    #[serde(rename = "RESERVES_BREAKDOWN")]
    /// A detailed breakdown of reserves backing a stablecoin asset, covering various categories such as cash, cryptocurrency, bonds, and
    /// other investments for transparency.
    pub reserves_breakdown: Option<Vec<OCCoreReservesBreakdown>>,
    #[serde(rename = "WEBSITE_URL")]
    /// The link for the official project website.
    pub website_url: Option<String>,
    #[serde(rename = "BLOG_URL")]
    /// The link for the official blog.
    pub blog_url: Option<String>,
    #[serde(rename = "WHITE_PAPER_URL")]
    /// A white paper, also written as "whitepaper", a document released by the project that gives investors technical information about its concept,
    /// its purpose, how it works, etc.
    pub white_paper_url: Option<String>,
    #[serde(rename = "OTHER_DOCUMENT_URLS")]
    /// Other documents that might be relevant to the asset, they should all be .PDFs.
    pub other_document_urls: Option<Vec<OCCoreDocumentURLs>>,
    #[serde(rename = "ASSET_INDUSTRIES")]
    /// The asset industries that asset operates in.
    pub asset_industries: Option<Vec<AssetIndustry>>,
    #[serde(rename = "PRICE_USD")]
    /// Denotes the current value / price of the asset in USD. This value is used to populate toplists and is calculated based on real-time market data.
    pub price_usd: f64,
    #[serde(rename = "PRICE_USD_SOURCE")]
    /// Denotes the source we used for the USD value / price.
    pub price_usd_source: String,
    #[serde(rename = "PRICE_USD_LAST_UPDATE_TS")]
    /// The Unix timestamp of the last update to the USD value / price of the asset.
    pub price_usd_last_update_ts: i64,
    #[serde(rename = "PRICE_CONVERSION_ASSET")]
    /// Denotes the convesion asset ID, SYMBOL and ASSET_TYPE.
    pub price_conversion_asset: Option<OCCorePriceConversionAsset>,
    #[serde(rename = "PRICE_CONVERSION_RATE")]
    /// Denotes the current value / price of USD in the requested quote asset.
    pub price_conversion_rate: Option<f64>,
    #[serde(rename = "PRICE_CONVERSION_VALUE")]
    /// Denotes the current value / price of the asset in the requested quote currency.
    pub price_conversion_value: Option<f64>,
    #[serde(rename = "PRICE_CONVERSION_SOURCE")]
    /// Denotes the source we used for the conversion asset value / price.
    pub price_conversion_source: Option<String>,
    #[serde(rename = "PRICE_CONVERSION_LAST_UPDATE_TS")]
    /// The Unix timestamp of the last update to the conversion asset value / price.
    pub price_conversion_last_update_ts: Option<i64>,
    #[serde(rename = "MKT_CAP_PENALTY")]
    /// The total penalty applied to the mkt cap due to liquidity or quality of data. Comment example: The value is reduced to 0.01% of the original due to
    /// low volume on B+ ranked exchanges or because it is only trading on a limited number of exchanges.
    pub mkt_cap_penalty: Option<f64>,
    #[serde(rename = "CIRCULATING_MKT_CAP_USD")]
    /// Calculated as the product of the asset's circulating supply and its current price quoted in USD (we sometimes apply a MKT_CAP_PENALTY depending on
    /// liquidity conditions). This is used to rank assets in toplists based on their circulating market capitalization.
    pub circulating_mkt_cap_usd: f64,
    #[serde(rename = "TOTAL_MKT_CAP_USD")]
    /// Calculated as the product of the asset's total supply and its current price quoted in USD (we sometimes apply a MKT_CAP_PENALTY depending on
    /// liquidity conditions). This figure gives an overview of the total value of all issued tokens for a given asset.
    pub total_mkt_cap_usd: f64,
    #[serde(rename = "CIRCULATING_MKT_CAP_CONVERSION")]
    /// Calculated as the product of the asset's circulating supply and its current price quoted in conversion asset (we sometimes apply a MKT_CAP_PENALTY
    /// depending on liquidity conditions). We calculate this field by multiplying the CIRCULATING_MKT_CAP_USD and the PRICE_CONVERSION_VALUE.
    pub circulating_mkt_cap_conversion: Option<f64>,
    #[serde(rename = "TOTAL_MKT_CAP_CONVERSION")]
    /// Calculated as the product of the asset's total supply and its current price quoted in conversion asset (we sometimes apply a MKT_CAP_PENALTY
    /// depending on liquidity conditions). We calculate this field by multiplying the TOTAL_MKT_CAP_USD and the PRICE_CONVERSION_VALUE.
    pub total_mkt_cap_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Aggregated 24 hours volume of the asset traded accross instruments that are quoted in USD on spot markets that we consider top tier, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset on top tier spot markets.
    pub spot_moving_24_hour_quote_volume_top_tier_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_DIRECT_USD")]
    /// Aggregated 24 hours volume of the asset traded accross instruments that are quoted in USD on all the intergarted spot markets, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset.
    pub spot_moving_24_hour_quote_volume_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Aggregated 24 hours volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot top tier markets, every trade volume is converted to USD using the most accuarte
    /// conversion price at the time of the trade. These markets meet specific quality criteria, offering a more curated view of trading activity.
    pub spot_moving_24_hour_quote_volume_top_tier_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD")]
    /// Aggregated 24 hours volume of the asset traded accross all instruments on all the integrated spot markets, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot markets, every trade volume is converted to USD using the most accuarte conversion
    /// price at the time of the trade. Useful for understanding demand and trading interest.
    pub spot_moving_24_hour_quote_volume_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_CONVERSION")]
    /// Aggregated 24 hours volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in conversion asset.
    /// We calculate this field by multiplying the SPOT_MOVING_24_HOUR_QUOTE_VOLUME_TOP_TIER_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_24_hour_quote_volume_top_tier_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_QUOTE_VOLUME_CONVERSION")]
    /// Aggregated 24 hours volume of the asset traded accross all instruments on all the integrated spot markets.
    /// We calculate this field by multiplying the SPOT_MOVING_24_HOUR_QUOTE_VOLUME_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_24_hour_quote_volume_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Aggregated 7 days volume of the asset traded accross instruments that are quoted in USD on spot markets that we consider top tier, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset on top tier spot markets.
    pub spot_moving_7_day_quote_volume_top_tier_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_DIRECT_USD")]
    /// Aggregated 7 days volume of the asset traded accross instruments that are quoted in USD on all the intergarted spot markets, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset.
    pub spot_moving_7_day_quote_volume_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Aggregated 7 days volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot top tier markets, every trade volume is converted to USD using the most accuarte
    /// conversion price at the time of the trade. These markets meet specific quality criteria, offering a more curated view of trading activity.
    pub spot_moving_7_day_quote_volume_top_tier_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_USD")]
    /// Aggregated 7 days volume of the asset traded accross all instruments on all the integrated spot markets, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot markets, every trade volume is converted to USD using the most accuarte conversion
    /// price at the time of the trade. Useful for understanding demand and trading interest.
    pub spot_moving_7_day_quote_volume_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_CONVERSION")]
    /// Aggregated 7 days volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in conversion asset.
    /// We calculate this field by multiplying the SPOT_MOVING_7_DAY_QUOTE_VOLUME_TOP_TIER_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_7_day_quote_volume_top_tier_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_QUOTE_VOLUME_CONVERSION")]
    /// Aggregated 7 days volume of the asset traded accross all instruments on all the integrated spot markets.
    /// We calculate this field by multiplying the SPOT_MOVING_7_DAY_QUOTE_VOLUME_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_7_day_quote_volume_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_DIRECT_USD")]
    /// Aggregated 30 days volume of the asset traded accross instruments that are quoted in USD on spot markets that we consider top tier, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset on top tier spot markets.
    pub spot_moving_30_day_quote_volume_top_tier_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_DIRECT_USD")]
    /// Aggregated 30 days volume of the asset traded accross instruments that are quoted in USD on all the intergarted spot markets, quoted in USD.
    /// Provides insights into the USD liquidity and trading activity of the asset.
    pub spot_moving_30_day_quote_volume_direct_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_USD")]
    /// Aggregated 30 days volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot top tier markets, every trade volume is converted to USD using the most accuarte
    /// conversion price at the time of the trade. These markets meet specific quality criteria, offering a more curated view of trading activity.
    pub spot_moving_30_day_quote_volume_top_tier_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_USD")]
    /// Aggregated 30 days volume of the asset traded accross all instruments on all the integrated spot markets, quoted in USD.
    /// This is the sum of all the trade volumes on all the spot markets, every trade volume is converted to USD using the most accuarte conversion
    /// price at the time of the trade. Useful for understanding demand and trading interest.
    pub spot_moving_30_day_quote_volume_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_CONVERSION")]
    /// Aggregated 30 days volume of the asset traded accross all instruments on spot markets that we consider top tier, quoted in conversion asset.
    /// We calculate this field by multiplying the SPOT_MOVING_30_DAY_QUOTE_VOLUME_TOP_TIER_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_30_day_quote_volume_top_tier_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_QUOTE_VOLUME_CONVERSION")]
    /// Aggregated 30 days volume of the asset traded accross all instruments on all the integrated spot markets.
    /// We calculate this field by multiplying the SPOT_MOVING_30_DAY_QUOTE_VOLUME_USD and the PRICE_CONVERSION_VALUE.
    pub spot_moving_30_day_quote_volume_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_USD")]
    /// The difference between the value of the asset quoted in USD 24 hours ago and the latest USD price.
    pub spot_moving_24_hour_change_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD")]
    /// The percentage difference between the value of the asset quoted in USD 24 hours ago and the latest USD price.
    pub spot_moving_24_hour_change_percentage_usd: f64,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_CONVERSION")]
    /// The approximate difference between the value of the asset quoted conversion currency 23 hours ago and now.
    /// We calculate this field by multiplying the SPOT_MOVING_24_HOUR_CHANGE_USD and the PRICE_CONVERSION_VALUE.
    /// This figure does not take into account the volatility of the conversion asset quoted in USD.
    pub spot_moving_24_hour_change_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_CONVERSION")]
    /// The percentage difference between the value of the asset quoted in USD 24 hours ago and the latest USD price.
    /// This is the same as the SPOT_MOVING_24_HOUR_CHANGE_PERCENTAGE_USD just adding it here for easier access.
    pub spot_moving_24_hour_change_percentage_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_USD")]
    /// The difference between the value of the asset quoted in USD 7 days ago and the latest USD price.
    pub spot_moving_7_day_change_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_PERCENTAGE_USD")]
    /// The percentage difference between the value of the asset quoted in USD 7 days ago and the latest USD price.
    pub spot_moving_7_day_change_percentage_usd: f64,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_CONVERSION")]
    /// The approximate difference between the value of the asset quoted conversion currency 6 days ago and current day.
    /// We calculate this field by multiplying the SPOT_MOVING_7_DAY_CHANGE_USD and the PRICE_CONVERSION_VALUE.
    /// This figure does not take into account the volatility of the conversion asset quoted in USD.
    pub spot_moving_7_day_change_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_7_DAY_CHANGE_PERCENTAGE_CONVERSION")]
    /// The percentage difference between the value of the asset quoted in USD 7 days ago and the latest USD price.
    /// This is the same as the SPOT_MOVING_7_DAY_CHANGE_PERCENTAGE_USD just adding it here for easier access.
    pub spot_moving_7_day_change_percentage_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_USD")]
    /// The difference between the value of the asset quoted in USD 30 days ago and the latest USD price.
    pub spot_moving_30_day_change_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_PERCENTAGE_USD")]
    /// The percentage difference between the value of the asset quoted in USD 30 days ago and the latest USD price.
    pub spot_moving_30_day_change_percentage_usd: f64,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_CONVERSION")]
    /// The approximate difference between the value of the asset quoted conversion currency 29 days ago and current day.
    /// We calculate this field by multiplying the SPOT_MOVING_30_DAY_CHANGE_USD and the PRICE_CONVERSION_VALUE.
    /// This figure does not take into account the volatility of the conversion asset quoted in USD.
    pub spot_moving_30_day_change_conversion: Option<f64>,
    #[serde(rename = "SPOT_MOVING_30_DAY_CHANGE_PERCENTAGE_CONVERSION")]
    /// The percentage difference between the value of the asset quoted in USD 30 days ago and the latest USD price.
    /// This is the same as the SPOT_MOVING_30_DAY_CHANGE_PERCENTAGE_USD just adding it here for easier access.
    pub spot_moving_30_day_change_percentage_conversion: Option<f64>,
    #[serde(rename = "TOPLIST_BASE_RANK")]
    /// Indicates the asset's position in our global asset ranking. There are multiple ranks, each is determined by at least one factor,
    /// such as asset launch date, market cap, trading volume, etc...
    pub toplist_base_rank: Option<OCCoreToplistRank>,
    #[serde(rename = "ASSET_DESCRIPTION")]
    /// The long form description in markdown for this asset.
    pub asset_description: String,
    #[serde(rename = "ASSET_DESCRIPTION_SUMMARY")]
    /// The short form description text only for this asset.
    pub asset_description_summary: String,
    #[serde(rename = "PROJECT_LEADERS")]
    /// An array of individuals that contains founders, whitepaper authors, investors, resechers, and other important people related to a project.
    pub project_leaders: Option<Vec<OCCoreProjectLeader>>,
    #[serde(rename = "ASSOCIATED_CONTACT_DETAILS")]
    /// Associated contact addresses for the team members, employees or affiliated contacts.
    pub associated_contact_details: Option<OCCoreContactDetails>,
    #[serde(rename = "SEO_TITLE")]
    /// The title that appears when you post this page on social media.
    pub seo_title: String,
    #[serde(rename = "SEO_DESCRIPTION")]
    /// The description that appears when you post this page on social media.
    pub seo_description: String, 
}


// On-Chain Core: Historical Supply Day


/// On-Chain Core: Historical Supply Day
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OCCoreSupply {
    #[serde(rename = "UNIT")]
    /// The unit of the historical period update: HOUR for hour and DAY for day.
    pub unit: String,
    #[serde(rename = "TYPE")]
    /// The type of the message.
    pub type_: String,
    #[serde(rename = "ASSET_ID")]
    /// The unique identifier for the asset.
    pub asset_id: i32,
    #[serde(rename = "SYMBOL")]
    /// The unique identifier for the asset.
    pub symbol: String,
    #[serde(rename = "TIMESTAMP")]
    /// The unix timestamp when this asset historical supply day data was saved.
    pub timestamp: i64,
    #[serde(rename = "SUPPLY_CIRCULATING")]
    /// Also referred to as free float or public float. The number of asset parts (coins/tokens) that are available to be traded and it excludes burnt
    /// supply and locked supply.
    pub supply_circulating: Option<f64>,
    #[serde(rename = "SUPPLY_TOTAL")]
    /// The number of asset parts (coins/tokens) that have been issued so far excluding burnt tokens. (supply_circulating + supply_locked).
    pub supply_total: Option<f64>,
    #[serde(rename = "SUPPLY_BURNT")]
    /// The number of asset parts (coins/tokens) that have been sent to addresses/locations that are no longer accessible.
    /// They are permanently removed from the circulating supply on purpose, this does not include lost tokens sent to wallets that do not exist
    /// or sent to wallets that users no longer have access to, the address of burnt tokens is determined by the project team.
    pub supply_burnt: Option<f64>,
    #[serde(rename = "SUPPLY_MAX")]
    /// The maximum number of asset parts (coins/tokens) that will ever be issued (supply_circulating + supply_burnt + supply_locked + all supply that
    /// has not been issued yet but is planned to be issued in the future). For assets (coins/tokens) that have infinite supply, we use -1.
    pub supply_max: Option<f64>,
    #[serde(rename = "SUPPLY_STAKED")]
    /// The current number of asset parts (coins/tokens) that are locked as part of PoS and PoS partial chains.
    pub supply_staked: Option<f64>,
    #[serde(rename = "SUPPLY_FUTURE")]
    /// The number of asset parts (coins/tokens) that are planned to be issued in the future. (supply_max - supply_issued).
    pub supply_future: Option<f64>,
    #[serde(rename = "SUPPLY_ISSUED")]
    /// The number of asset parts (coins/tokens) that have been issued so far. (supply_circulating + supply_locked + supply_burnt).
    pub supply_issued: Option<f64>,
    #[serde(rename = "SUPPLY_LOCKED")]
    /// The number of asset parts (coins/tokens) that are currently not transferable until certain conditions are met. Locked supply is generally held by
    /// team members, DAOs, foundations, bridges, stakers, liquidity pools, etc.
    pub supply_locked: Option<f64>,
}