Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Transaction History
This guide covers querying and filtering transaction history in the Privacy Boost Android SDK.Basic Usage
val transactions = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(
txType = null,
tokenAddress = null,
limit = null
)
}
for (tx in transactions) {
println("${tx.txType}: ${tx.amount} - ${tx.txHash}")
}
Transaction Type
data class Transaction(
val txHash: String, // Transaction hash
val txType: String, // "deposit", "withdraw", or "transfer"
val tokenAddress: String, // Token contract address
val amount: String, // Amount in wei
val direction: String, // "incoming" or "outgoing"
val senderPubKey: String, // Sender's public key
val receiverPubKeys: List<String>, // Receiver public keys
val createdAt: ULong // Unix timestamp
)
Filtering History
By Transaction Type
// Only deposits
val deposits = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = "deposit", tokenAddress = null, limit = null)
}
// Only withdrawals
val withdrawals = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = "withdraw", tokenAddress = null, limit = null)
}
// Only transfers
val transfers = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = "transfer", tokenAddress = null, limit = null)
}
By Token
val usdcHistory = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(
txType = null,
tokenAddress = "0x...usdc-address",
limit = null
)
}
With Limit
// Get last 10 transactions
val recent = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = null, tokenAddress = null, limit = 10u)
}
Combined Filters
// Last 5 USDC deposits
val recentUsdcDeposits = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(
txType = "deposit",
tokenAddress = "0x...usdc-address",
limit = 5u
)
}
Filter Parameters
| Parameter | Type | Description |
|---|---|---|
txType | String? | Filter by type: "deposit", "withdraw", "transfer" |
tokenAddress | String? | Filter by token contract address |
limit | UInt? | Maximum number of results |
ViewModel Integration
class TransactionViewModel(private val sdk: PrivacyBoost) : ViewModel() {
private val _transactions = MutableStateFlow<List<Transaction>>(emptyList())
val transactions: StateFlow<List<Transaction>> = _transactions.asStateFlow()
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
private val _filter = MutableStateFlow("all")
val filter: StateFlow<String> = _filter.asStateFlow()
fun setFilter(type: String) {
_filter.value = type
loadTransactions()
}
fun loadTransactions() {
viewModelScope.launch {
_isLoading.value = true
try {
val typeFilter = if (_filter.value == "all") null else _filter.value
val result = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(
txType = typeFilter,
tokenAddress = null,
limit = 50u
)
}
_transactions.value = result
} catch (e: SDKError) {
println("Failed to load transactions: $e")
}
_isLoading.value = false
}
}
}
Displaying Transactions in Compose
@Composable
fun TransactionHistory(viewModel: TransactionViewModel) {
val transactions by viewModel.transactions.collectAsState()
val isLoading by viewModel.isLoading.collectAsState()
val filter by viewModel.filter.collectAsState()
val filters = listOf("all", "deposit", "withdraw", "transfer")
LaunchedEffect(Unit) {
viewModel.loadTransactions()
}
Column {
// Filter tabs
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
filters.forEach { type ->
FilterChip(
selected = filter == type,
onClick = { viewModel.setFilter(type) },
label = { Text(type.replaceFirstChar { it.uppercase() }) }
)
}
}
// Transaction list
if (isLoading) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.CenterHorizontally))
} else if (transactions.isEmpty()) {
Text("No transactions found", color = Color.Gray)
} else {
LazyColumn {
items(transactions) { tx ->
TransactionRow(transaction = tx)
}
}
}
}
}
@Composable
fun TransactionRow(transaction: Transaction) {
val icon = when (transaction.txType) {
"deposit" -> Icons.Default.ArrowDownward
"withdraw" -> Icons.Default.ArrowUpward
"transfer" -> Icons.Default.SwapHoriz
else -> Icons.Default.Circle
}
val dateFormatter = SimpleDateFormat("MMM d, yyyy HH:mm", Locale.getDefault())
val formattedDate = dateFormatter.format(Date(transaction.createdAt.toLong() * 1000))
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = icon, contentDescription = transaction.txType)
Spacer(modifier = Modifier.width(12.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = transaction.txType.replaceFirstChar { it.uppercase() },
style = MaterialTheme.typography.titleSmall
)
Text(
text = formattedDate,
style = MaterialTheme.typography.bodySmall,
color = Color.Gray
)
}
Text(
text = transaction.amount,
style = MaterialTheme.typography.bodyMedium
)
}
}
Error Handling
try {
val transactions = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = null, tokenAddress = null, limit = null)
}
} catch (e: SDKError) {
when (e) {
is SDKError.NotAuthenticated ->
println("Please log in first")
is SDKError.NetworkError ->
println("Network error: ${e.message}")
else ->
println("Failed to get history: $e")
}
}
Best Practices
1. Paginate Results
For apps with many transactions, use thelimit parameter:
suspend fun loadPage(pageSize: UInt = 20u): List<Transaction> {
return withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = null, tokenAddress = null, limit = pageSize)
}
}
2. Refresh After Operations
Fetch updated history after deposits, withdrawals, or transfers:val shieldResult = withContext(Dispatchers.IO) {
sdk.shield(tokenAddress = tokenAddress, amount = amount)
}
// Refresh transaction list
val updatedHistory = withContext(Dispatchers.IO) {
sdk.getTransactionHistory(txType = null, tokenAddress = null, limit = 20u)
}