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