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