1use serde::{Deserialize, Serialize};
8use serde_json::Value as JsonValue;
9
10#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
17pub struct IcrcTokenReport {
18 pub schema_version: u32,
19 pub ledger_canister_id: String,
20 pub fetched_at: String,
21 pub source_endpoint: String,
22 pub fetched_by: String,
23 pub token_name: String,
24 pub token_symbol: String,
25 pub decimals: u8,
26 pub transfer_fee: String,
27 pub total_supply: String,
28 pub minting_account_owner: Option<String>,
29 pub minting_account_subaccount_hex: Option<String>,
30 pub supported_standards: Vec<IcrcTokenStandardRow>,
31 pub metadata: Vec<IcrcTokenMetadataRow>,
32}
33
34#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
41pub struct IcrcIndexReport {
42 pub schema_version: u32,
43 pub ledger_canister_id: String,
44 pub fetched_at: String,
45 pub source_endpoint: String,
46 pub fetched_by: String,
47 pub index_canister_id: Option<String>,
48 pub index_error: Option<String>,
49}
50
51#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
58pub struct IcrcTransactionsReport {
59 pub schema_version: u32,
60 pub ledger_canister_id: String,
61 pub fetched_at: String,
62 pub source_endpoint: String,
63 pub fetched_by: String,
64 pub requested_start: String,
65 pub requested_limit: u32,
66 pub follow_archives: bool,
67 pub log_length: Option<String>,
68 pub blocks: Vec<IcrcTransactionBlockRow>,
69 pub archived_blocks: Vec<IcrcArchivedBlocksRow>,
70 pub followed_archive_blocks: Vec<IcrcFollowedArchiveBlockRow>,
71 pub archive_follow_errors: Vec<IcrcArchiveFollowErrorRow>,
72}
73
74#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
81pub struct IcrcBlockTypesReport {
82 pub schema_version: u32,
83 pub ledger_canister_id: String,
84 pub fetched_at: String,
85 pub source_endpoint: String,
86 pub fetched_by: String,
87 pub block_types: Vec<IcrcBlockTypeRow>,
88}
89
90#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
97pub struct IcrcArchivesReport {
98 pub schema_version: u32,
99 pub ledger_canister_id: String,
100 pub from_canister_id: Option<String>,
101 pub fetched_at: String,
102 pub source_endpoint: String,
103 pub fetched_by: String,
104 pub archives: Vec<IcrcArchiveRow>,
105}
106
107#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
114pub struct IcrcTipCertificateReport {
115 pub schema_version: u32,
116 pub ledger_canister_id: String,
117 pub fetched_at: String,
118 pub source_endpoint: String,
119 pub fetched_by: String,
120 pub certificate_present: bool,
121 pub certificate_hex: Option<String>,
122 pub certificate_bytes: Option<usize>,
123 pub hash_tree_hex: Option<String>,
124 pub hash_tree_bytes: Option<usize>,
125}
126
127#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
134pub struct IcrcCapabilitiesReport {
135 pub schema_version: u32,
136 pub ledger_canister_id: String,
137 pub fetched_at: String,
138 pub source_endpoint: String,
139 pub fetched_by: String,
140 pub supported_standards: Vec<IcrcTokenStandardRow>,
141 pub capabilities: Vec<IcrcCapabilityRow>,
142}
143
144#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
151pub struct IcrcCapabilityRow {
152 pub capability: String,
153 pub method: String,
154 pub status: IcrcCapabilityStatus,
155 pub details: Option<String>,
156 pub error: Option<String>,
157}
158
159#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
166#[serde(rename_all = "snake_case")]
167pub enum IcrcCapabilityStatus {
168 Available,
170 Unsupported,
172 Error,
174}
175
176impl IcrcCapabilityStatus {
177 #[must_use]
179 pub const fn as_str(self) -> &'static str {
180 match self {
181 Self::Available => "available",
182 Self::Unsupported => "unsupported",
183 Self::Error => "error",
184 }
185 }
186}
187
188#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
195pub struct IcrcTokenStandardRow {
196 pub name: String,
197 pub url: String,
198}
199
200#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
207pub struct IcrcTokenMetadataRow {
208 pub key: String,
209 pub value_type: IcrcMetadataValueKind,
210 pub value: JsonValue,
211}
212
213#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
220#[serde(rename_all = "snake_case")]
221pub enum IcrcMetadataValueKind {
222 Nat,
224 Int,
226 Text,
228 Blob,
230}
231
232impl IcrcMetadataValueKind {
233 #[must_use]
235 pub const fn as_str(self) -> &'static str {
236 match self {
237 Self::Nat => "nat",
238 Self::Int => "int",
239 Self::Text => "text",
240 Self::Blob => "blob",
241 }
242 }
243}
244
245#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
252pub struct IcrcTransactionBlockRow {
253 pub index: String,
254 pub block_type: Option<String>,
255 pub transaction_kind: Option<String>,
256 pub timestamp_unix_nanos: Option<String>,
257 pub amount_base_units: Option<String>,
258 pub raw_block: JsonValue,
259}
260
261#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
268pub struct IcrcArchivedBlocksRow {
269 pub callback_canister_id: String,
270 pub callback_method: String,
271 pub ranges: Vec<IcrcArchivedRangeRow>,
272}
273
274#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
281pub struct IcrcArchivedRangeRow {
282 pub start: String,
283 pub length: String,
284}
285
286#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
293pub struct IcrcFollowedArchiveBlockRow {
294 pub archive_canister_id: String,
295 pub callback_method: String,
296 pub index: String,
297 pub block_type: Option<String>,
298 pub transaction_kind: Option<String>,
299 pub timestamp_unix_nanos: Option<String>,
300 pub amount_base_units: Option<String>,
301 pub raw_block: JsonValue,
302}
303
304#[cfg(test)]
305mod tests {
306 use super::*;
307
308 #[test]
309 fn capability_status_labels_are_stable() {
310 for (status, label) in [
311 (IcrcCapabilityStatus::Available, "available"),
312 (IcrcCapabilityStatus::Unsupported, "unsupported"),
313 (IcrcCapabilityStatus::Error, "error"),
314 ] {
315 assert_eq!(
316 serde_json::to_string(&status).unwrap(),
317 format!("\"{label}\"")
318 );
319 assert_eq!(status.as_str(), label);
320 }
321 }
322
323 #[test]
324 fn metadata_value_kind_labels_round_trip() {
325 for (kind, label) in [
326 (IcrcMetadataValueKind::Nat, "nat"),
327 (IcrcMetadataValueKind::Int, "int"),
328 (IcrcMetadataValueKind::Text, "text"),
329 (IcrcMetadataValueKind::Blob, "blob"),
330 ] {
331 assert_eq!(
332 serde_json::to_string(&kind).unwrap(),
333 format!("\"{label}\"")
334 );
335 assert_eq!(
336 serde_json::from_str::<IcrcMetadataValueKind>(&format!("\"{label}\"")).unwrap(),
337 kind
338 );
339 assert_eq!(kind.as_str(), label);
340 }
341 }
342}
343
344#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
351pub struct IcrcArchiveFollowErrorRow {
352 pub callback_canister_id: String,
353 pub callback_method: String,
354 pub ranges: Vec<IcrcArchivedRangeRow>,
355 pub error: String,
356}
357
358#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
365pub struct IcrcBlockTypeRow {
366 pub block_type: String,
367 pub url: String,
368}
369
370#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
377pub struct IcrcArchiveRow {
378 pub canister_id: String,
379 pub start: String,
380 pub end: String,
381}