Find Wallet Transactions
This example prints all transactions with an output involving a specific wallet address:
#include <chrono> #include <signal.h> // Third-party libraries #include <nlohmann/json.hpp> #include <ogmios/client.hpp> #include <spdlog/spdlog.h> using json = nlohmann::json; using namespace nlohmann::literals; using namespace std::chrono_literals; namespace { volatile bool global_exit = false; } auto shutdown_handler(int s) -> void { spdlog::info("Program received signal {}", s); global_exit = true; } // shutdown_handler auto main() -> int { signal(SIGINT, shutdown_handler); // Stop the program with CTRL-C spdlog::set_level(spdlog::level::info); // Set global log level // The address for which to find transactions. const auto target_addr = std::string( "addr_test1vzpwq95z3xyum8vqndgdd9mdnmafh3djcxnc6jemlgdmswcve6tkw" ); // Create a client to manage the Ogmios server connection. auto client = ogmios::Client("ws://localhost:1337"); // Setup the logging callback to print information to stdout. client.setLoggerCallback( [](int level, const std::string& msg) { spdlog::log(static_cast<spdlog::level::level_enum>(level), msg); } ); // Create a point from the last block of the Byron era (pre-prod) const auto point = R"( [ { "slot": 84242, "id": "45899e8002b27df291e09188bfe3aeb5397ac03546a7d0ead93aa2500860f1af" } ] )"_json; // Get the intersection of the last Byron block in order to begine the // transaction search whithin the Shelley era. if (client.findIntersection(point).wait_for(2s) != std::future_status::ready) { throw std::runtime_error("Timed out waiting for intersection"); } // Use batching to improve performance. constexpr size_t batch_size = 1000; auto future_results = std::vector<std::future<json>>(batch_size); // Start streaming blocks from the origin. auto num_txs_found = (size_t)0; while (!global_exit) { // Batch up the requests without waiting for a response. for (size_t i = 0; i < batch_size; i++) { if (global_exit) break; // exit with CTRL-C future_results[i] = client.nextBlock(); } // Process the reponses in order but without waiting for all the // batched responses to complete before starting. for (auto& future : future_results) { if (global_exit) break; // exit with CTRL-C if (future.wait_for(2s) != std::future_status::ready) { throw std::runtime_error("Timed out waiting for next block"); } auto query_result = future.get(); if (query_result["result"]["direction"] != "forward") continue; auto tip = query_result["result"]["tip"]; auto block = query_result["result"]["block"]; if (block.contains("transactions")) { for (auto& tx : block["transactions"]) { if (tx.contains("outputs")) { for (auto& output : tx["outputs"]) { if (output.contains("address") && output["address"] == target_addr) { num_txs_found++; spdlog::info( "Transaction #{}: {}", num_txs_found, tx["id"].get<std::string>() ); break; } } } } } // Stop the program once we reach the tip of the chain. if (block["height"] == tip["height"]) { spdlog::info( "Reached chain tip at slot {}", tip["slot"].dump() ); global_exit = true; break; } } } return 0; } // main
Example output: