ic_query/icrc/model/contracts/reports/account_history.rs
1//! Module: icrc::model::contracts::reports::account_history
2//!
3//! Responsibility: serialized ICRC account-history page, cache, and row contracts.
4//! Does not own: ledger-wide history, requests, live transport, cache mechanics, or rendering.
5//! Boundary: owns the stable JSON and persisted snapshot shapes for indexed account history.
6
7use crate::cache::{CacheCollectionCompleteness, CacheValidationStatus};
8use serde::{Deserialize as SerdeDeserialize, Serialize};
9use serde_json::Value as JsonValue;
10
11///
12/// IcrcAccountTransactionPageData
13///
14/// Source-layer account-history page returned by an ICRC index canister.
15///
16
17#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
18pub struct IcrcAccountTransactionPageData {
19 /// Index canister that answered the query.
20 pub index_canister_id: String,
21 /// Account balance reported by the index.
22 pub balance: String,
23 /// Oldest transaction id known for the account.
24 pub oldest_transaction_id: Option<String>,
25 /// Cursor for requesting the next older page.
26 pub next_start: Option<String>,
27 /// Ledger token symbol.
28 pub token_symbol: String,
29 /// Ledger token decimals.
30 pub decimals: u8,
31 /// Account transactions in index response order.
32 pub transactions: Vec<IcrcAccountTransactionRow>,
33}
34
35///
36/// IcrcAccountTransactionPageReport
37///
38/// Serializable report for a backward page of ICRC index account transactions.
39///
40
41#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
42pub struct IcrcAccountTransactionPageReport {
43 /// Shared record, flattened in serialized output.
44 #[serde(flatten)]
45 pub provenance: super::IcrcReportProvenance,
46 /// Queried account owner principal.
47 pub account_owner: String,
48 /// Queried subaccount as normalized hex.
49 pub subaccount_hex: Option<String>,
50 /// Exclusive block-index cursor supplied by the caller.
51 pub requested_start: Option<String>,
52 /// Maximum number of transactions requested.
53 pub requested_limit: u32,
54 /// Validated index response and ledger display metadata.
55 #[serde(flatten)]
56 pub page: IcrcAccountTransactionPageData,
57}
58
59///
60/// IcrcAccountTransactionSnapshot
61///
62/// Complete persisted account-history snapshot collected by exhausting the index API.
63///
64
65#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
66#[serde(deny_unknown_fields)]
67pub struct IcrcAccountTransactionSnapshot {
68 /// Cache schema version.
69 pub schema_version: u32,
70 /// IC API endpoint used for ledger and index calls.
71 pub source_endpoint: String,
72 /// Collection start timestamp supplied by the refresh caller's clock.
73 pub collection_started_at: String,
74 /// Collection completion timestamp derived from the start plus monotonic elapsed time.
75 pub collection_completed_at: String,
76 /// Collector identity.
77 pub fetched_by: String,
78 /// Ledger canister whose transactions were indexed.
79 pub ledger_canister_id: String,
80 /// Verified index canister used for every page.
81 pub index_canister_id: String,
82 /// Queried account owner principal.
83 pub account_owner: String,
84 /// Queried subaccount as normalized hex.
85 pub subaccount_hex: Option<String>,
86 /// Account balance reported by the first index page.
87 pub balance: String,
88 /// Ledger token symbol used for text rendering.
89 pub token_symbol: String,
90 /// Ledger token decimals used for text rendering.
91 pub decimals: u8,
92 /// Highest collected transaction id.
93 pub newest_transaction_id: Option<String>,
94 /// Lowest collected transaction id.
95 pub oldest_transaction_id: Option<String>,
96 /// Complete-collection evidence.
97 pub completeness: CacheCollectionCompleteness,
98 /// Canonical newest-first account transactions.
99 pub transactions: Vec<IcrcAccountTransactionRow>,
100}
101
102///
103/// IcrcAccountTransactionRefreshReport
104///
105/// Serializable forced-refresh outcome for one complete account-history cache.
106///
107
108#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
109pub struct IcrcAccountTransactionRefreshReport {
110 /// Report schema version.
111 pub schema_version: u32,
112 /// Ledger canister whose account history was collected.
113 pub ledger_canister_id: String,
114 /// Verified index canister used for every page.
115 pub index_canister_id: String,
116 /// Queried account owner principal.
117 pub account_owner: String,
118 /// Queried subaccount as normalized hex.
119 pub subaccount_hex: Option<String>,
120 /// Number of unique transactions published.
121 pub transaction_count: usize,
122 /// Highest published transaction id.
123 pub newest_transaction_id: Option<String>,
124 /// Lowest published transaction id.
125 pub oldest_transaction_id: Option<String>,
126 /// Maximum transactions requested per source page.
127 pub page_size: u32,
128 /// Number of source pages collected.
129 pub page_count: u32,
130 /// Whether the source guarantees one point-in-time snapshot.
131 pub point_in_time_guaranteed: bool,
132 /// Whether a prior complete cache existed.
133 pub replaced_existing_cache: bool,
134 /// Non-fatal error encountered finalizing the refresh-attempt sidecar.
135 pub attempt_finalization_error: Option<String>,
136 /// Collection start timestamp.
137 pub collection_started_at: String,
138 /// Collection completion timestamp.
139 pub collection_completed_at: String,
140 /// IC API endpoint used for ledger and index calls.
141 pub source_endpoint: String,
142 /// Collector identity.
143 pub fetched_by: String,
144 /// Published complete-cache path.
145 pub cache_path: String,
146 /// Refresh-attempt sidecar path.
147 pub refresh_attempt_path: String,
148 /// Refresh lock path.
149 pub refresh_lock_path: String,
150}
151
152///
153/// IcrcAccountTransactionListReport
154///
155/// Serializable cache-only view over a complete account-history snapshot.
156///
157
158#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
159pub struct IcrcAccountTransactionListReport {
160 /// Report schema version.
161 pub schema_version: u32,
162 /// Ledger canister whose cached history is shown.
163 pub ledger_canister_id: String,
164 /// Verified index canister used to collect the cache.
165 pub index_canister_id: String,
166 /// Cached account owner principal.
167 pub account_owner: String,
168 /// Cached subaccount as normalized hex.
169 pub subaccount_hex: Option<String>,
170 /// Maximum cached rows requested by this view.
171 pub requested_limit: u32,
172 /// Stable requested ordering name.
173 pub sort: String,
174 /// Total rows in the complete cache.
175 pub total_transaction_count: usize,
176 /// Rows returned by this view.
177 pub returned_transaction_count: usize,
178 /// Highest transaction id in the complete cache.
179 pub newest_transaction_id: Option<String>,
180 /// Lowest transaction id in the complete cache.
181 pub oldest_transaction_id: Option<String>,
182 /// Account balance captured from the first index page.
183 pub balance: String,
184 /// Ledger token symbol used for text rendering.
185 pub token_symbol: String,
186 /// Ledger token decimals used for text rendering.
187 pub decimals: u8,
188 /// Complete collection start timestamp.
189 pub collection_started_at: String,
190 /// Complete collection finish timestamp.
191 pub collection_completed_at: String,
192 /// IC API endpoint represented by the cache.
193 pub source_endpoint: String,
194 /// Collector identity.
195 pub fetched_by: String,
196 /// Whether source exhaustion was proven.
197 pub complete: bool,
198 /// Whether the source guaranteed one point-in-time snapshot.
199 pub point_in_time_guaranteed: bool,
200 /// Maximum transactions requested per source page.
201 pub page_size: u32,
202 /// Number of source pages collected.
203 pub page_count: u32,
204 /// Complete-cache path read by this view.
205 pub cache_path: String,
206 /// Selected cached rows in requested order.
207 pub transactions: Vec<IcrcAccountTransactionRow>,
208}
209
210///
211/// IcrcAccountTransactionCacheStatusReport
212///
213/// Serializable local cache and latest-refresh status.
214///
215
216#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
217pub struct IcrcAccountTransactionCacheStatusReport {
218 /// Report schema version.
219 pub schema_version: u32,
220 /// Ledger canister in the requested cache identity.
221 pub ledger_canister_id: String,
222 /// Account owner in the requested cache identity.
223 pub account_owner: String,
224 /// Subaccount in the requested cache identity.
225 pub subaccount_hex: Option<String>,
226 /// IC API endpoint in the requested cache identity.
227 pub source_endpoint: String,
228 /// Whether a cache file exists at the expected path.
229 pub found: bool,
230 /// Validation summary when a cache file exists.
231 pub cache: Option<IcrcAccountTransactionCacheSummary>,
232 /// Expected complete-cache path.
233 pub expected_cache_path: String,
234 /// Refresh-attempt sidecar path.
235 pub refresh_attempt_path: String,
236 /// Refresh lock path.
237 pub refresh_lock_path: String,
238 /// Latest refresh-attempt state when present.
239 pub latest_attempt: Option<IcrcAccountTransactionRefreshAttemptStatus>,
240}
241
242///
243/// IcrcAccountTransactionCacheSummary
244///
245/// Serializable validation summary for one complete account-history cache.
246///
247
248#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
249pub struct IcrcAccountTransactionCacheSummary {
250 /// Stable cache validation status.
251 pub cache_status: CacheValidationStatus,
252 /// Validation error when the existing cache is invalid.
253 pub cache_error: Option<String>,
254 /// Verified index canister when the cache is valid.
255 pub index_canister_id: Option<String>,
256 /// Number of cached transaction rows.
257 pub transaction_count: usize,
258 /// Highest cached transaction id.
259 pub newest_transaction_id: Option<String>,
260 /// Lowest cached transaction id.
261 pub oldest_transaction_id: Option<String>,
262 /// Maximum transactions requested per source page.
263 pub page_size: u32,
264 /// Number of source pages collected.
265 pub page_count: u32,
266 /// Whether source exhaustion was proven.
267 pub complete: bool,
268 /// Whether the source guaranteed one point-in-time snapshot.
269 pub point_in_time_guaranteed: bool,
270 /// Complete collection start timestamp.
271 pub collection_started_at: String,
272 /// Complete collection finish timestamp.
273 pub collection_completed_at: String,
274 /// Complete-cache path.
275 pub cache_path: String,
276}
277
278///
279/// IcrcAccountTransactionRefreshAttemptStatus
280///
281/// Serializable status of the latest complete-history refresh attempt.
282///
283
284#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
285pub struct IcrcAccountTransactionRefreshAttemptStatus {
286 /// Explicit or resolved index canister recorded by the attempt.
287 pub index_canister_id: Option<String>,
288 /// Validated shared lifecycle evidence.
289 #[serde(flatten)]
290 pub lifecycle: crate::cache::SnapshotRefreshAttemptStatus,
291}
292
293///
294/// IcrcAccountRow
295///
296/// Serializable ICRC account identity used in account-transaction rows.
297///
298
299#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
300pub struct IcrcAccountRow {
301 /// ICRC account owner principal when the index uses structured accounts.
302 pub owner: Option<String>,
303 /// Optional 32-byte subaccount as lowercase hex.
304 pub subaccount_hex: Option<String>,
305 /// Legacy ICP account identifier when the index returns identifier text.
306 pub account_identifier: Option<String>,
307}
308
309///
310/// IcrcAccountTransactionRow
311///
312/// Serializable projected and lossless JSON representation of one index transaction.
313///
314
315#[derive(Clone, Debug, Eq, PartialEq, SerdeDeserialize, Serialize)]
316pub struct IcrcAccountTransactionRow {
317 /// Ledger block index of the transaction.
318 pub id: String,
319 /// Index-reported transaction kind.
320 pub kind: String,
321 /// Ledger transaction timestamp as Unix nanoseconds when present.
322 pub timestamp_unix_nanos: Option<String>,
323 /// Operation amount in ledger base units when the operation carries one.
324 pub amount_base_units: Option<String>,
325 /// Operation fee in ledger base units when the operation carries one.
326 pub fee_base_units: Option<String>,
327 /// Source account when present.
328 pub from: Option<IcrcAccountRow>,
329 /// Destination account when present.
330 pub to: Option<IcrcAccountRow>,
331 /// Spender account when present.
332 pub spender: Option<IcrcAccountRow>,
333 /// Operation memo as lowercase hex when present.
334 pub memo_hex: Option<String>,
335 /// Caller-supplied creation time as Unix nanoseconds when present.
336 pub created_at_time_unix_nanos: Option<String>,
337 /// Approval expiry as Unix nanoseconds when present.
338 pub expires_at_unix_nanos: Option<String>,
339 /// Expected prior allowance in base units when present.
340 pub expected_allowance_base_units: Option<String>,
341 /// Lossless JSON projection of every typed transaction field returned by the index.
342 pub raw_transaction: JsonValue,
343}