Skip to main content

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}