diff --git a/src/index/blockfilterindex.h b/src/index/blockfilterindex.h
--- a/src/index/blockfilterindex.h
+++ b/src/index/blockfilterindex.h
@@ -68,4 +68,31 @@
                                std::vector<uint256> &hashes_out) const;
 };
 
+/**
+ * Get a block filter index by type. Returns nullptr if index has not been
+ * initialized or was already destroyed.
+ */
+BlockFilterIndex *GetBlockFilterIndex(BlockFilterType filter_type);
+
+/** Iterate over all running block filter indexes, invoking fn on each. */
+void ForEachBlockFilterIndex(std::function<void(BlockFilterIndex &)> fn);
+
+/**
+ * Initialize a block filter index for the given type if one does not already
+ * exist. Returns true if a new index is created and false if one has already
+ * been initialized.
+ */
+bool InitBlockFilterIndex(BlockFilterType filter_type, size_t n_cache_size,
+                          bool f_memory = false, bool f_wipe = false);
+
+/**
+ * Destroy the block filter index with the given type. Returns false if no such
+ * index exists. This just releases the allocated memory and closes the database
+ * connection, it does not delete the index data.
+ */
+bool DestroyBlockFilterIndex(BlockFilterType filter_type);
+
+/** Destroy all open block filter indexes. */
+void DestroyAllBlockFilterIndexes();
+
 #endif // BITCOIN_INDEX_BLOCKFILTERINDEX_H
diff --git a/src/index/blockfilterindex.cpp b/src/index/blockfilterindex.cpp
--- a/src/index/blockfilterindex.cpp
+++ b/src/index/blockfilterindex.cpp
@@ -99,6 +99,8 @@
 
 }; // namespace
 
+static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
+
 BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type,
                                    size_t n_cache_size, bool f_memory,
                                    bool f_wipe)
@@ -462,3 +464,30 @@
     }
     return true;
 }
+
+BlockFilterIndex *GetBlockFilterIndex(BlockFilterType filter_type) {
+    auto it = g_filter_indexes.find(filter_type);
+    return it != g_filter_indexes.end() ? &it->second : nullptr;
+}
+
+void ForEachBlockFilterIndex(std::function<void(BlockFilterIndex &)> fn) {
+    for (auto &entry : g_filter_indexes) {
+        fn(entry.second);
+    }
+}
+
+bool InitBlockFilterIndex(BlockFilterType filter_type, size_t n_cache_size,
+                          bool f_memory, bool f_wipe) {
+    auto result = g_filter_indexes.emplace(
+        std::piecewise_construct, std::forward_as_tuple(filter_type),
+        std::forward_as_tuple(filter_type, n_cache_size, f_memory, f_wipe));
+    return result.second;
+}
+
+bool DestroyBlockFilterIndex(BlockFilterType filter_type) {
+    return g_filter_indexes.erase(filter_type);
+}
+
+void DestroyAllBlockFilterIndexes() {
+    g_filter_indexes.clear();
+}
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -278,4 +278,44 @@
     filter_index.Stop();
 }
 
+BOOST_FIXTURE_TEST_CASE(blockfilter_index_init_destroy, BasicTestingSetup) {
+    BlockFilterIndex *filter_index;
+
+    filter_index = GetBlockFilterIndex(BlockFilterType::BASIC);
+    BOOST_CHECK(filter_index == nullptr);
+
+    BOOST_CHECK(
+        InitBlockFilterIndex(BlockFilterType::BASIC, 1 << 20, true, false));
+
+    filter_index = GetBlockFilterIndex(BlockFilterType::BASIC);
+    BOOST_CHECK(filter_index != nullptr);
+    BOOST_CHECK(filter_index->GetFilterType() == BlockFilterType::BASIC);
+
+    // Initialize returns false if index already exists.
+    BOOST_CHECK(
+        !InitBlockFilterIndex(BlockFilterType::BASIC, 1 << 20, true, false));
+
+    int iter_count = 0;
+    ForEachBlockFilterIndex(
+        [&iter_count](BlockFilterIndex &_index) { iter_count++; });
+    BOOST_CHECK_EQUAL(iter_count, 1);
+
+    BOOST_CHECK(DestroyBlockFilterIndex(BlockFilterType::BASIC));
+
+    // Destroy returns false because index was already destroyed.
+    BOOST_CHECK(!DestroyBlockFilterIndex(BlockFilterType::BASIC));
+
+    filter_index = GetBlockFilterIndex(BlockFilterType::BASIC);
+    BOOST_CHECK(filter_index == nullptr);
+
+    // Reinitialize index.
+    BOOST_CHECK(
+        InitBlockFilterIndex(BlockFilterType::BASIC, 1 << 20, true, false));
+
+    DestroyAllBlockFilterIndexes();
+
+    filter_index = GetBlockFilterIndex(BlockFilterType::BASIC);
+    BOOST_CHECK(filter_index == nullptr);
+}
+
 BOOST_AUTO_TEST_SUITE_END()