Examples » 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:

Image
Example Find Transactions Output

Open Example on Gitlab