Skip to main content

ic_query/icrc/model/contracts/reports/
ledger.rs

1//! Module: icrc::model::contracts::reports::ledger
2//!
3//! Responsibility: serialized ICRC ledger metadata, capability, and history contracts.
4//! Does not own: account-index history, requests, live transport, archive following, or rendering.
5//! Boundary: preserves raw ledger, block, archive, certificate, and capability fields.
6
7use crate::icrc::{IcrcTokenMetadataRow, IcrcTokenStandardRow};
8use serde::Serialize;
9use serde_json::Value as JsonValue;
10
11///
12/// IcrcTokenReport
13///
14/// Serializable report for generic ICRC ledger token metadata.
15///
16
17#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
18pub struct IcrcTokenReport {
19    pub schema_version: u32,
20    pub ledger_canister_id: String,
21    pub fetched_at: String,
22    pub source_endpoint: String,
23    pub fetched_by: String,
24    pub token_name: String,
25    pub token_symbol: String,
26    pub decimals: u8,
27    pub transfer_fee: String,
28    pub total_supply: String,
29    pub minting_account_owner: Option<String>,
30    pub minting_account_subaccount_hex: Option<String>,
31    pub supported_standards: Vec<IcrcTokenStandardRow>,
32    pub metadata: Vec<IcrcTokenMetadataRow>,
33}
34
35///
36/// IcrcIndexReport
37///
38/// Serializable report for one generic ICRC-106 index discovery lookup.
39///
40
41#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
42pub struct IcrcIndexReport {
43    pub schema_version: u32,
44    pub ledger_canister_id: String,
45    pub fetched_at: String,
46    pub source_endpoint: String,
47    pub fetched_by: String,
48    pub index_canister_id: Option<String>,
49    pub index_error: Option<String>,
50}
51
52///
53/// IcrcTransactionsReport
54///
55/// Serializable report for a generic ICRC ledger transaction/block history page.
56///
57
58#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
59pub struct IcrcTransactionsReport {
60    pub schema_version: u32,
61    pub ledger_canister_id: String,
62    pub fetched_at: String,
63    pub source_endpoint: String,
64    pub fetched_by: String,
65    pub requested_start: String,
66    pub requested_limit: u32,
67    pub follow_archives: bool,
68    pub log_length: Option<String>,
69    pub blocks: Vec<IcrcTransactionBlockRow>,
70    pub archived_blocks: Vec<IcrcArchivedBlocksRow>,
71    pub followed_archive_blocks: Vec<IcrcFollowedArchiveBlockRow>,
72    pub archive_follow_errors: Vec<IcrcArchiveFollowErrorRow>,
73}
74
75///
76/// IcrcBlockTypesReport
77///
78/// Serializable report for generic ICRC-3 supported block type discovery.
79///
80
81#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
82pub struct IcrcBlockTypesReport {
83    pub schema_version: u32,
84    pub ledger_canister_id: String,
85    pub fetched_at: String,
86    pub source_endpoint: String,
87    pub fetched_by: String,
88    pub block_types: Vec<IcrcBlockTypeRow>,
89}
90
91///
92/// IcrcArchivesReport
93///
94/// Serializable report for generic ICRC-3 archive range discovery.
95///
96
97#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
98pub struct IcrcArchivesReport {
99    pub schema_version: u32,
100    pub ledger_canister_id: String,
101    pub from_canister_id: Option<String>,
102    pub fetched_at: String,
103    pub source_endpoint: String,
104    pub fetched_by: String,
105    pub archives: Vec<IcrcArchiveRow>,
106}
107
108///
109/// IcrcTipCertificateReport
110///
111/// Serializable report for a generic ICRC-3 ledger tip certificate.
112///
113
114#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
115pub struct IcrcTipCertificateReport {
116    pub schema_version: u32,
117    pub ledger_canister_id: String,
118    pub fetched_at: String,
119    pub source_endpoint: String,
120    pub fetched_by: String,
121    pub certificate_present: bool,
122    pub certificate_hex: Option<String>,
123    pub certificate_bytes: Option<usize>,
124    pub hash_tree_hex: Option<String>,
125    pub hash_tree_bytes: Option<usize>,
126}
127
128///
129/// IcrcCapabilitiesReport
130///
131/// Serializable report for generic ICRC ledger endpoint capabilities.
132///
133
134#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
135pub struct IcrcCapabilitiesReport {
136    pub schema_version: u32,
137    pub ledger_canister_id: String,
138    pub fetched_at: String,
139    pub source_endpoint: String,
140    pub fetched_by: String,
141    pub supported_standards: Vec<IcrcTokenStandardRow>,
142    pub capabilities: Vec<IcrcCapabilityRow>,
143}
144
145///
146/// IcrcCapabilityRow
147///
148/// Serializable row for one probed generic ICRC ledger capability.
149///
150
151#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
152pub struct IcrcCapabilityRow {
153    pub capability: String,
154    pub method: String,
155    pub status: IcrcCapabilityStatus,
156    pub details: Option<String>,
157    pub error: Option<String>,
158}
159
160///
161/// IcrcCapabilityStatus
162///
163/// Result of probing one optional ICRC ledger capability.
164///
165
166#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
167#[serde(rename_all = "snake_case")]
168pub enum IcrcCapabilityStatus {
169    /// The target answered the capability query successfully.
170    Available,
171    /// The target does not export the probed query method.
172    Unsupported,
173    /// The target exports the method but the query failed.
174    Error,
175}
176
177impl IcrcCapabilityStatus {
178    /// Return the stable JSON and text label.
179    #[must_use]
180    pub const fn as_str(self) -> &'static str {
181        match self {
182            Self::Available => "available",
183            Self::Unsupported => "unsupported",
184            Self::Error => "error",
185        }
186    }
187}
188
189///
190/// IcrcTransactionBlockRow
191///
192/// Serializable row for one ICRC-3 block returned by a ledger canister.
193///
194
195#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
196pub struct IcrcTransactionBlockRow {
197    pub index: String,
198    pub block_type: Option<String>,
199    pub transaction_kind: Option<String>,
200    pub timestamp_unix_nanos: Option<String>,
201    pub amount_base_units: Option<String>,
202    pub raw_block: JsonValue,
203}
204
205///
206/// IcrcArchivedBlocksRow
207///
208/// Serializable row for one ICRC-3 archive callback returned by a ledger canister.
209///
210
211#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
212pub struct IcrcArchivedBlocksRow {
213    pub callback_canister_id: String,
214    pub callback_method: String,
215    pub ranges: Vec<IcrcArchivedRangeRow>,
216}
217
218///
219/// IcrcArchivedRangeRow
220///
221/// Serializable row for one ICRC-3 archived block range.
222///
223
224#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
225pub struct IcrcArchivedRangeRow {
226    pub start: String,
227    pub length: String,
228}
229
230///
231/// IcrcFollowedArchiveBlockRow
232///
233/// Serializable row for one ICRC-3 block fetched from an archive callback.
234///
235
236#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
237pub struct IcrcFollowedArchiveBlockRow {
238    pub archive_canister_id: String,
239    pub callback_method: String,
240    pub index: String,
241    pub block_type: Option<String>,
242    pub transaction_kind: Option<String>,
243    pub timestamp_unix_nanos: Option<String>,
244    pub amount_base_units: Option<String>,
245    pub raw_block: JsonValue,
246}
247
248#[cfg(test)]
249mod tests {
250    use super::*;
251
252    #[test]
253    fn capability_status_labels_are_stable() {
254        for (status, label) in [
255            (IcrcCapabilityStatus::Available, "available"),
256            (IcrcCapabilityStatus::Unsupported, "unsupported"),
257            (IcrcCapabilityStatus::Error, "error"),
258        ] {
259            assert_eq!(
260                serde_json::to_string(&status).unwrap(),
261                format!("\"{label}\"")
262            );
263            assert_eq!(status.as_str(), label);
264        }
265    }
266}
267
268///
269/// IcrcArchiveFollowErrorRow
270///
271/// Serializable row for one archive callback that could not be followed.
272///
273
274#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
275pub struct IcrcArchiveFollowErrorRow {
276    pub callback_canister_id: String,
277    pub callback_method: String,
278    pub ranges: Vec<IcrcArchivedRangeRow>,
279    pub error: String,
280}
281
282///
283/// IcrcBlockTypeRow
284///
285/// Serializable row for one supported ICRC-3 block type.
286///
287
288#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
289pub struct IcrcBlockTypeRow {
290    pub block_type: String,
291    pub url: String,
292}
293
294///
295/// IcrcArchiveRow
296///
297/// Serializable row for one ICRC-3 archive range.
298///
299
300#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
301pub struct IcrcArchiveRow {
302    pub canister_id: String,
303    pub start: String,
304    pub end: String,
305}