Skip to main content

Transaction History

This guide covers querying and filtering transaction history in the Privacy Boost TypeScript SDK.

Basic Usage

const transactions = await sdk.vault.getTransactionHistory();

for (const tx of transactions) {
  console.log(`${tx.type}: ${tx.amount?.toString()} - ${tx.txHash}`);
}

Transaction Type

interface Transaction {
  txHash: Hex;
  type: TransactionType;           // 'deposit' | 'withdraw' | 'transfer'
  direction: TransactionDirection;  // 'incoming' | 'outgoing'
  status: TransactionStatus;       // 'pending' | 'completed' | 'failed'
  tokenAddress?: Hex;
  amount?: bigint;
  receivers: ReceiverTransfer[];
  createdAt: number;
  updatedAt: number;
  to?: Hex;
  from?: Hex;
  error?: string;
  tokenSymbol?: string;
  commitment?: Hex;
  complianceStatus?: ComplianceStatus;  // 'PENDING' | 'LEGIT' | 'ILLICIT'
}

Filtering History

By Transaction Type

// Only deposits
const deposits = await sdk.vault.getTransactionHistory({ type: 'deposit' });

// Only withdrawals
const withdrawals = await sdk.vault.getTransactionHistory({ type: 'withdraw' });

// Only transfers
const transfers = await sdk.vault.getTransactionHistory({ type: 'transfer' });

By Token

const usdcHistory = await sdk.vault.getTransactionHistory({
  tokenAddress: '0x...usdc-address',
});

With Limit

// Get last 10 transactions
const recent = await sdk.vault.getTransactionHistory({ limit: 10 });

Combined Filters

// Last 5 USDC deposits
const recentUsdcDeposits = await sdk.vault.getTransactionHistory({
  type: 'deposit',
  tokenAddress: '0x...usdc-address',
  limit: 5,
});

Filter Parameters

interface TransactionHistoryParams {
  type?: 'deposit' | 'withdraw' | 'transfer';
  tokenAddress?: string;
  limit?: number;
}

UI Example

import { useState, useEffect } from 'react';

function TransactionHistory() {
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState<string>('all');

  useEffect(() => {
    async function load() {
      setLoading(true);
      const params: TransactionHistoryParams = { limit: 50 };
      if (filter !== 'all') {
        params.type = filter as any;
      }
      const txs = await sdk.vault.getTransactionHistory(params);
      setTransactions(txs);
      setLoading(false);
    }
    load();
  }, [filter]);

  const formatAmount = (amount: bigint, decimals = 18) => {
    return (Number(amount) / 10 ** decimals).toFixed(4);
  };

  return (
    <div>
      {/* Filter Tabs */}
      <div className="tabs">
        {['all', 'deposit', 'withdraw', 'transfer'].map((type) => (
          <button
            key={type}
            onClick={() => setFilter(type)}
            className={filter === type ? 'active' : ''}
          >
            {type.charAt(0).toUpperCase() + type.slice(1)}
          </button>
        ))}
      </div>

      {loading && <div>Loading transactions...</div>}

      {!loading && transactions.length === 0 && <p>No transactions found</p>}

      <table>
        <thead>
          <tr>
            <th>Type</th>
            <th>Amount</th>
            <th>Status</th>
            <th>Date</th>
          </tr>
        </thead>
        <tbody>
          {transactions.map((tx) => (
            <tr key={tx.txHash}>
              <td>
                {tx.type}
                {tx.direction === 'incoming' && ' (received)'}
              </td>
              <td>{tx.amount ? formatAmount(tx.amount) : '-'}</td>
              <td>{tx.status}</td>
              <td>{new Date(tx.createdAt).toLocaleDateString()}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Error Handling

try {
  const transactions = await sdk.vault.getTransactionHistory();
} catch (error) {
  if (error instanceof PrivacyBoostError) {
    switch (error.code) {
      case 'NOT_AUTHENTICATED':
        console.log('Please log in first');
        break;
      case 'NETWORK_ERROR':
        console.log('Failed to fetch history');
        break;
      default:
        console.log('Error:', error.message);
    }
  }
}

Best Practices

1. Paginate Results

const recent = await sdk.vault.getTransactionHistory({ limit: 20 });

2. Refresh After Operations

const shieldResult = await sdk.vault.shield({ tokenAddress, amount });

// Refresh transaction list
const updatedHistory = await sdk.vault.getTransactionHistory({ limit: 20 });

3. Poll for Pending Transactions

function useTransactionPolling(intervalMs = 15000) {
  const [transactions, setTransactions] = useState<Transaction[]>([]);

  useEffect(() => {
    async function fetch() {
      const txs = await sdk.vault.getTransactionHistory({ limit: 50 });
      setTransactions(txs);
    }

    fetch();
    const interval = setInterval(fetch, intervalMs);
    return () => clearInterval(interval);
  }, [intervalMs]);

  return transactions;
}

Next Steps