Transaction Tracking System Development
Naive transaction monitoring implementation — polling JSON-RPC every N seconds: eth_getBlockByNumber, iterate transactions, find required address. With 10+ addresses under load this quickly becomes a problem: growing lag, rate-limit from RPC provider, missed transactions on brief outages. Correct system is built on different architecture — event-driven, with chain reorganization and guaranteed processing.
Architecture: Three Main Approaches
1. WebSocket Subscriptions (Suitable for Small Systems)
Ethereum WebSocket API supports eth_subscribe:
-
newHeads— new blocks -
logs— smart contract events by filter -
newPendingTransactions— mempool (unreliable, don't use for finance)
const { ethers } = require("ethers");
const provider = new ethers.WebSocketProvider(process.env.WS_RPC_URL);
// Subscribe to ERC-20 Transfer events
const filter = {
address: USDC_CONTRACT,
topics: [
ethers.id("Transfer(address,address,uint256)"),
null,
ethers.zeroPadValue(WATCHED_ADDRESS, 32), // only incoming
],
};
provider.on(filter, async (log) => {
const parsed = iface.parseLog(log);
await processIncomingTransfer({
txHash: log.transactionHash,
from: parsed.args.from,
amount: parsed.args.value,
blockNumber: log.blockNumber,
});
});
Problem: WebSocket connection drops. Need reconnect with recovery of missed events — request eth_getLogs for missed block range on reconnect.
2. Indexer Service (for Medium and Large Systems)
The Graph, Ponder, or custom indexer based on eth_getLogs with cursor. Scheme:
RPC Node → Indexer Worker → PostgreSQL (indexed events) → API → Clients
Indexer stores last_processed_block, on restart continues from same place. Batch requests: eth_getLogs for block range (recommended 1000–2000 blocks at a time).
3. Webhook Providers (Fastest Implementation)
Helius (Solana), Alchemy (EVM), QuickNode Streams take monitoring on themselves, calling your endpoint on events. Suitable when infrastructure simplicity is more important than full control.
Chain Reorganization (chain reorg)
This is the most non-obvious place. Blockchain reorg — normal phenomenon, especially at shallow depths. Transaction with 3 confirmations can disappear. System that doesn't handle reorg periodically shows users "paid" orders that later get reversed.
Rule: don't mark transaction as final until safe depth is reached:
| Network | Safe Depth | Finality |
|---|---|---|
| Ethereum | 12+ confirmations (~2.5 min) | Checkpoint (slots, ~13 min) |
| Bitcoin | 6 confirmations (~60 min) | Probabilistic |
| Polygon PoS | 256 confirmations (~8 min) | Checkpoint in Ethereum |
| Solana | finalized (~15 sec) | Definite |
Implementing state machine for transaction:
pending → confirming (1+ conf) → confirmed (12+ conf) → finalized
↓
reorged → needs_retry
On detecting reorg (block with our transaction was replaced): revert status, notify, recheck.
Storage and Indexing
Minimal transaction table schema:
CREATE TABLE tracked_transactions (
id BIGSERIAL PRIMARY KEY,
tx_hash VARCHAR(66) NOT NULL,
network VARCHAR(20) NOT NULL,
block_number BIGINT,
block_hash VARCHAR(66), -- for reorg detection
from_address VARCHAR(42),
to_address VARCHAR(42),
value_raw NUMERIC(78, 0), -- wei/lamports, no precision loss
token_contract VARCHAR(42),
status VARCHAR(20) DEFAULT 'pending',
confirmations INT DEFAULT 0,
metadata JSONB,
first_seen_at TIMESTAMPTZ DEFAULT now(),
confirmed_at TIMESTAMPTZ,
UNIQUE(tx_hash, network)
);
CREATE INDEX idx_tracked_tx_address ON tracked_transactions(to_address);
CREATE INDEX idx_tracked_tx_status ON tracked_transactions(status)
WHERE status NOT IN ('finalized', 'failed');
block_hash allows detecting reorg: if block at our block_number has different hash — fork occurred.
Monitoring the Indexer Itself
Metric indexer_lag_blocks — how much indexer lags behind chain head. If lag > 50 blocks — alert: either RPC fell or indexer overloaded. Add to Prometheus/Grafana or at least Uptime Robot with webhook.
What's Included in System Development
- Event retrieval component (WebSocket + fallback polling)
- Reorg handler with status rollback
- Confirmation worker (updates confirmations count)
- REST/WebSocket API for frontend
- Webhook delivery for external systems (with retry and dead-letter queue)
- Dashboard of current indexer state







