Skip to main content

Transaction History

Track and manage your transaction history with metadata, labels, and search capabilities.

Overview

The Transaction History utility helps you:

  • Record and track transaction status
  • Search and filter transactions
  • Add labels and notes for organization
  • Calculate statistics and totals
  • Persist history to file

Installation

import {
createTxHistory,
createMemoryTxHistory,
formatTxHistoryStats,
formatTxRecord,
} from 'cardano-devkit';

Creating a History Manager

// File-based persistence (default)
const history = createTxHistory();

// With custom options
const history = createTxHistory({
filePath: './my-tx-history.json',
autoSave: true,
maxRecords: 1000,
});

// In-memory only (no persistence)
const memoryHistory = createMemoryTxHistory();

Recording Transactions

Adding a Transaction

const record = history.add({
txHash: "abc123def456...",
status: "submitted",
direction: "outgoing",
amount: 5_000_000n,
fee: 200_000n,
addresses: {
from: ["addr_test1..."],
to: ["addr_test2...", "addr_test3..."],
},
network: "Preprod",
metadata: { purpose: "payment" },
labels: ["urgent"],
note: "Monthly payment",
});

Transaction Status

type TxStatus =
| "pending" // Created but not submitted
| "submitted" // Submitted to network
| "confirmed" // Confirmed on-chain
| "failed" // Failed to submit or confirm
| "expired"; // TTL expired

// Update status
history.updateStatus(txHash, "confirmed", {
block: 12345,
slot: 67890,
confirmedAt: new Date().toISOString(),
});

Transaction Direction

type TxDirection =
| "incoming" // Received funds
| "outgoing" // Sent funds
| "self" // Self-transfer
| "unknown"; // Cannot determine

Querying Transactions

Get by Hash

const record = history.get(txHash);
if (record) {
console.log("Status:", record.status);
console.log("Amount:", record.amount);
}

Get All

const allRecords = history.getAll();
console.log(`Total: ${allRecords.length} transactions`);

Filter by Status

const confirmed = history.getByStatus("confirmed");
const failed = history.getByStatus("failed");
const pending = history.getPending(); // pending + submitted

Filter by Direction

const incoming = history.getByDirection("incoming");
const outgoing = history.getByDirection("outgoing");

Filter by Label

const urgent = history.getByLabel("urgent");
const payments = history.getByLabel("payment");

Filter by Date Range

const thisWeek = history.getInRange(
new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
new Date()
);
// Search by address, note, label, or tx hash
const results = history.search("addr_test1");
const payments = history.search("payment");

Labels and Notes

Adding Labels

history.addLabel(txHash, "important");
history.addLabel(txHash, "reviewed");

// Find by label
const important = history.getByLabel("important");

Removing Labels

history.removeLabel(txHash, "urgent");

Setting Notes

history.setNote(txHash, "Payment for consulting services - Invoice #123");

const record = history.get(txHash);
console.log("Note:", record?.note);

Statistics

const stats = history.getStats();

console.log("Total transactions:", stats.total);
console.log("Pending:", stats.pending);
console.log("Confirmed:", stats.confirmed);
console.log("Failed:", stats.failed);
console.log("Incoming count:", stats.incoming);
console.log("Outgoing count:", stats.outgoing);
console.log("Total received:", stats.totalReceived);
console.log("Total sent:", stats.totalSent);
console.log("Total fees paid:", stats.totalFees);
console.log("First transaction:", stats.firstTx);
console.log("Last transaction:", stats.lastTx);

// Format for display
console.log(formatTxHistoryStats(stats));

Persistence

Manual Save/Load

// Save to file
history.save();

// Reload from file
history.reload();

Export/Import

// Export as JSON string
const json = history.exportJson();
fs.writeFileSync("backup.json", json);

// Import from JSON
const json = fs.readFileSync("backup.json", "utf-8");
const count = history.importJson(json);
console.log(`Imported ${count} transactions`);

Removing Transactions

// Remove single transaction
history.remove(txHash);

// Clear all history
history.clear();

Formatting

Format a Single Record

const record = history.get(txHash);
if (record) {
console.log(formatTxRecord(record));
}

Output:

📤 abc123de...f456 [confirmed]
Amount: 5.000000 ADA
Fee: 0.200000 ADA
Recorded: 2024-01-15T10:30:00.000Z
Labels: urgent, payment

Types

TxRecord

interface TxRecord {
txHash: string;
status: TxStatus;
direction: TxDirection;
block?: number;
slot?: number;
amount: bigint;
fee?: bigint;
addresses: {
from: string[];
to: string[];
};
assets?: Record<string, bigint>;
metadata?: Record<string, unknown>;
labels?: string[];
note?: string;
network: string;
recordedAt: string;
confirmedAt?: string;
error?: string;
}

TxHistoryStats

interface TxHistoryStats {
total: number;
pending: number;
confirmed: number;
failed: number;
incoming: number;
outgoing: number;
totalReceived: bigint;
totalSent: bigint;
totalFees: bigint;
firstTx?: string;
lastTx?: string;
}

TxHistoryOptions

interface TxHistoryOptions {
filePath?: string; // Default: "./.cardano-tx-history.json"
autoSave?: boolean; // Default: true
maxRecords?: number; // Default: 1000
}

CLI Usage

# List recent transactions
cardano-devkit history list

# Filter by status
cardano-devkit history list --status confirmed

# Filter by direction
cardano-devkit history list --direction incoming

# Show statistics
cardano-devkit history stats

# Search transactions
cardano-devkit history search "addr_test1"

# List pending transactions
cardano-devkit history pending

# Clear history (with confirmation)
cardano-devkit history clear

# Output as JSON
cardano-devkit history list --json

Integration with Transactions

Recording After Submit

import { sendAda, createTxHistory } from 'cardano-devkit';

const history = createTxHistory();

// Send transaction
const result = await sendAda(lucid, recipient, 5_000_000n);

// Record in history
history.add({
txHash: result.txHash,
status: "submitted",
direction: "outgoing",
amount: 5_000_000n,
fee: result.fee,
addresses: {
from: [await lucid.wallet().address()],
to: [recipient],
},
network: devKit.getNetwork(),
});

// Update when confirmed
await waitForConfirmation(lucid, result.txHash);
history.updateStatus(result.txHash, "confirmed");

Best Practices

  1. Record transactions immediately after submission
  2. Update status when transactions confirm or fail
  3. Use labels for categorization (e.g., "payment", "nft", "swap")
  4. Add notes for future reference
  5. Export backups regularly for important history
  6. Set reasonable maxRecords to prevent unbounded growth