diff --git a/cw_decred/lib/transaction_history.dart b/cw_decred/lib/transaction_history.dart
index d2abafbf4..37993e532 100644
--- a/cw_decred/lib/transaction_history.dart
+++ b/cw_decred/lib/transaction_history.dart
@@ -2,7 +2,6 @@ import 'package:mobx/mobx.dart';
 import 'package:cw_core/transaction_info.dart';
 import 'package:cw_core/transaction_history.dart';
 
-// NOTE: Methods currently not used.
 class DecredTransactionHistory extends TransactionHistoryBase<TransactionInfo> {
   DecredTransactionHistory() {
     transactions = ObservableMap<String, TransactionInfo>();
@@ -23,6 +22,17 @@ class DecredTransactionHistory extends TransactionHistoryBase<TransactionInfo> {
 
   Future<void> changePassword(String password) async {}
 
-  void _update(TransactionInfo transaction) =>
-      transactions[transaction.id] = transaction;
+  // update returns true if a known transaction that is not pending was found.
+  bool update(Map<String, TransactionInfo> txs) {
+    var foundOldTx = false;
+    txs.forEach((_, tx) {
+      if (!this.transactions.containsKey(tx.id) ||
+          this.transactions[tx.id]!.isPending) {
+        this.transactions[tx.id] = tx;
+      } else {
+        foundOldTx = true;
+      }
+    });
+    return foundOldTx;
+  }
 }
diff --git a/cw_decred/lib/wallet.dart b/cw_decred/lib/wallet.dart
index 7aec45cfb..d633954d4 100644
--- a/cw_decred/lib/wallet.dart
+++ b/cw_decred/lib/wallet.dart
@@ -51,6 +51,8 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
   final String _password;
   final idPrefix = "decred_";
   bool connecting = false;
+  int bestHeight = 0;
+  String bestHash = "";
   String persistantPeer = "";
   FeeCache feeRateFast = FeeCache(defaultFeeRate);
   FeeCache feeRateMedium = FeeCache(defaultFeeRate);
@@ -84,11 +86,32 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
     updateBalance();
   }
 
-  void performBackgroundTasks() {
+  void performBackgroundTasks() async {
     if (!checkSync()) {
       return;
     }
+    final res = libdcrwallet.bestBlock(walletInfo.name);
+    final decoded = json.decode(res);
+    final hash = decoded["hash"] ?? "";
+    if (this.bestHash != hash) {
+      this.bestHash = hash;
+      this.bestHeight = decoded["height"] ?? "";
+    }
     updateBalance();
+    var from = 0;
+    while (true) {
+      // Transactions are returned from newest to oldest. Loop fetching 5 txn
+      // at a time until we find a batch with txn that no longer need to be
+      // updated.
+      final txs = await this.fetchFiveTransactions(from);
+      if (txs.length == 0) {
+        return;
+      }
+      if (this.transactionHistory.update(txs)) {
+        return;
+      }
+      from += 5;
+    }
   }
 
   bool checkSync() {
@@ -335,21 +358,42 @@ abstract class DecredWalletBase extends WalletBase<DecredBalance,
 
   @override
   Future<Map<String, DecredTransactionInfo>> fetchTransactions() async {
-    // TODO: Read from libdcrwallet.
-    final txInfo = DecredTransactionInfo(
-      id: "3cbf3eb9523fd04e96dbaf98cdbd21779222cc8855ece8700494662ae7578e02",
-      amount: 1234567,
-      fee: 123,
-      direction: TransactionDirection.outgoing,
-      isPending: true,
-      date: DateTime.now(),
-      height: 0,
-      confirmations: 0,
-      to: "DsT4qJPPaYEuQRimfgvSKxKH3paysn1x3Nt",
-    );
-    return {
-      "3cbf3eb9523fd04e96dbaf98cdbd21779222cc8855ece8700494662ae7578e02": txInfo
-    };
+    return this.fetchFiveTransactions(0);
+  }
+
+  @override
+  Future<Map<String, DecredTransactionInfo>> fetchFiveTransactions(
+      int from) async {
+    final res =
+        libdcrwallet.listTransactions(walletInfo.name, from.toString(), "5");
+    final decoded = json.decode(res);
+    var txs = <String, DecredTransactionInfo>{};
+    for (final d in decoded) {
+      final txid = d["txid"] ?? "";
+      var direction = TransactionDirection.outgoing;
+      if (d["category"] == "receive") {
+        direction = TransactionDirection.incoming;
+      }
+      final amountDouble = d["amount"] ?? 0.0;
+      final amount = (amountDouble * 1e8).toInt().abs();
+      final feeDouble = d["fee"] ?? 0.0;
+      final fee = (feeDouble * 1e8).toInt().abs();
+      final confs = d["confirmations"] ?? 0;
+      final sendTime = d["time"] ?? 0;
+      final txInfo = DecredTransactionInfo(
+        id: txid,
+        amount: amount,
+        fee: fee,
+        direction: direction,
+        isPending: confs == 0,
+        date: DateTime.fromMillisecondsSinceEpoch(sendTime * 1000, isUtc: true),
+        height: 0,
+        confirmations: confs,
+        to: d["address"] ?? "",
+      );
+      txs[txid] = txInfo;
+    }
+    return txs;
   }
 
   @override