mod generic;
mod icp;
mod json;
use super::collection::AccountTransactionsPage;
use crate::candid_call::query_bytes;
use crate::icrc::{
ledger::IcrcAccount,
model::{IcrcAccountRow, IcrcAccountTransactionError, IcrcError},
};
use candid::{CandidType, Deserialize, Nat, Principal};
use ic_agent::Agent;
const INDEX_ACCOUNT_TRANSACTIONS_METHOD: &str = "get_account_transactions";
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
struct IcrcIndexAccountTransactionsArgs {
account: IcrcAccount,
start: Option<Nat>,
max_results: Nat,
}
#[derive(Default)]
struct TransactionSummary {
amount_base_units: Option<String>,
fee_base_units: Option<String>,
from: Option<IcrcAccountRow>,
to: Option<IcrcAccountRow>,
spender: Option<IcrcAccountRow>,
memo_hex: Option<String>,
created_at_time_unix_nanos: Option<String>,
expires_at_unix_nanos: Option<String>,
expected_allowance_base_units: Option<String>,
}
pub(super) async fn query_account_transaction_page(
agent: &Agent,
index_canister: &Principal,
account: &IcrcAccount,
start: Option<Nat>,
limit: u32,
) -> Result<AccountTransactionsPage, IcrcAccountTransactionError> {
let args = IcrcIndexAccountTransactionsArgs {
account: account.clone(),
start,
max_results: Nat::from(limit),
};
let bytes = query_bytes::<IcrcIndexAccountTransactionsArgs, IcrcError>(
agent,
index_canister,
INDEX_ACCOUNT_TRANSACTIONS_METHOD,
INDEX_ACCOUNT_TRANSACTIONS_METHOD,
&args,
)
.await?;
decode_account_transactions(&bytes, index_canister)
}
fn decode_account_transactions(
bytes: &[u8],
index_canister: &Principal,
) -> Result<AccountTransactionsPage, IcrcAccountTransactionError> {
match generic::decode(bytes, index_canister) {
Ok(result) => result,
Err(generic_error) => match icp::decode(bytes, index_canister) {
Ok(result) => result,
Err(icp_error) => Err(IcrcError::CandidDecode {
message: INDEX_ACCOUNT_TRANSACTIONS_METHOD,
reason: format!("generic ICRC index: {generic_error}; ICP index: {icp_error}"),
}
.into()),
},
}
}