use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTokenReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub token_name: String,
pub token_symbol: String,
pub decimals: u8,
pub transfer_fee: String,
pub total_supply: String,
pub minting_account_owner: Option<String>,
pub minting_account_subaccount_hex: Option<String>,
pub supported_standards: Vec<IcrcTokenStandardRow>,
pub metadata: Vec<IcrcTokenMetadataRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcIndexReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub index_canister_id: Option<String>,
pub index_error: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTransactionsReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub requested_start: String,
pub requested_limit: u32,
pub follow_archives: bool,
pub log_length: Option<String>,
pub blocks: Vec<IcrcTransactionBlockRow>,
pub archived_blocks: Vec<IcrcArchivedBlocksRow>,
pub followed_archive_blocks: Vec<IcrcFollowedArchiveBlockRow>,
pub archive_follow_errors: Vec<IcrcArchiveFollowErrorRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcBlockTypesReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub block_types: Vec<IcrcBlockTypeRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcArchivesReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub from_canister_id: Option<String>,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub archives: Vec<IcrcArchiveRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTipCertificateReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub certificate_present: bool,
pub certificate_hex: Option<String>,
pub certificate_bytes: Option<usize>,
pub hash_tree_hex: Option<String>,
pub hash_tree_bytes: Option<usize>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcCapabilitiesReport {
pub schema_version: u32,
pub ledger_canister_id: String,
pub fetched_at: String,
pub source_endpoint: String,
pub fetched_by: String,
pub supported_standards: Vec<IcrcTokenStandardRow>,
pub capabilities: Vec<IcrcCapabilityRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcCapabilityRow {
pub capability: String,
pub method: String,
pub status: IcrcCapabilityStatus,
pub details: Option<String>,
pub error: Option<String>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IcrcCapabilityStatus {
Available,
Unsupported,
Error,
}
impl IcrcCapabilityStatus {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Available => "available",
Self::Unsupported => "unsupported",
Self::Error => "error",
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTokenStandardRow {
pub name: String,
pub url: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTokenMetadataRow {
pub key: String,
pub value_type: IcrcMetadataValueKind,
pub value: JsonValue,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum IcrcMetadataValueKind {
Nat,
Int,
Text,
Blob,
}
impl IcrcMetadataValueKind {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Nat => "nat",
Self::Int => "int",
Self::Text => "text",
Self::Blob => "blob",
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcTransactionBlockRow {
pub index: String,
pub block_type: Option<String>,
pub transaction_kind: Option<String>,
pub timestamp_unix_nanos: Option<String>,
pub amount_base_units: Option<String>,
pub raw_block: JsonValue,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcArchivedBlocksRow {
pub callback_canister_id: String,
pub callback_method: String,
pub ranges: Vec<IcrcArchivedRangeRow>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcArchivedRangeRow {
pub start: String,
pub length: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcFollowedArchiveBlockRow {
pub archive_canister_id: String,
pub callback_method: String,
pub index: String,
pub block_type: Option<String>,
pub transaction_kind: Option<String>,
pub timestamp_unix_nanos: Option<String>,
pub amount_base_units: Option<String>,
pub raw_block: JsonValue,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn capability_status_labels_are_stable() {
for (status, label) in [
(IcrcCapabilityStatus::Available, "available"),
(IcrcCapabilityStatus::Unsupported, "unsupported"),
(IcrcCapabilityStatus::Error, "error"),
] {
assert_eq!(
serde_json::to_string(&status).unwrap(),
format!("\"{label}\"")
);
assert_eq!(status.as_str(), label);
}
}
#[test]
fn metadata_value_kind_labels_round_trip() {
for (kind, label) in [
(IcrcMetadataValueKind::Nat, "nat"),
(IcrcMetadataValueKind::Int, "int"),
(IcrcMetadataValueKind::Text, "text"),
(IcrcMetadataValueKind::Blob, "blob"),
] {
assert_eq!(
serde_json::to_string(&kind).unwrap(),
format!("\"{label}\"")
);
assert_eq!(
serde_json::from_str::<IcrcMetadataValueKind>(&format!("\"{label}\"")).unwrap(),
kind
);
assert_eq!(kind.as_str(), label);
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcArchiveFollowErrorRow {
pub callback_canister_id: String,
pub callback_method: String,
pub ranges: Vec<IcrcArchivedRangeRow>,
pub error: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcBlockTypeRow {
pub block_type: String,
pub url: String,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct IcrcArchiveRow {
pub canister_id: String,
pub start: String,
pub end: String,
}