diff --git a/include/solana.hpp b/include/solana.hpp index bb9497e..b5d7fd7 100644 --- a/include/solana.hpp +++ b/include/solana.hpp @@ -1138,6 +1138,13 @@ class WebSocketSubscriber { /// @brief remove the account change listener for the given id /// @param sub_id the id for which removing subscription is needed void removeAccountChangeListener(RequestIdType sub_id); + + int onSlotUpdate(Callback callback, + const Commitment &commitment = Commitment::FINALIZED, + Callback on_subscibe = nullptr, + Callback on_unsubscribe = nullptr); + + void removeSlotUpdateListener(RequestIdType sub_id); }; } // namespace subscription } // namespace rpc diff --git a/lib/solana.cpp b/lib/solana.cpp index 835995a..09cf96a 100644 --- a/lib/solana.cpp +++ b/lib/solana.cpp @@ -1137,6 +1137,31 @@ int WebSocketSubscriber::onAccountChange(const solana::PublicKey &pub_key, void WebSocketSubscriber::removeAccountChangeListener(RequestIdType sub_id) { sess->unsubscribe(sub_id); } + +int WebSocketSubscriber::onSlotUpdate(Callback callback, + const Commitment &commitment, + Callback on_subscibe, + Callback on_unsubscribe) { + // create parameters using the user provided input + json param = json::array(); + + // create a new request content + RequestContent req(curr_id, "slotsUpdatesSubscribe", + "slotsUpdatesUnsubscribe", callback, std::move(param), + on_subscibe, on_unsubscribe); + + // subscribe the new request content + sess->subscribe(req); + + // increase the curr_id so that it can be used for the next request content + curr_id += 2; + + return req.id; +} + +void WebSocketSubscriber::removeSlotUpdateListener(RequestIdType sub_id) { + sess->unsubscribe(sub_id); +} } // namespace subscription } // namespace rpc } // namespace solana \ No newline at end of file diff --git a/tests/main.cpp b/tests/main.cpp index 4a29aee..921c982 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -984,6 +984,24 @@ TEST_CASE("getBlocks") { CHECK_LE(Blocks[Blocks.size() - 1], latestslot); } +TEST_CASE("slot update subscribe and unsubscribe") { + solana::rpc::subscription::WebSocketSubscriber sub("api.devnet.solana.com", + "80"); + int num_notif, fin_number; + auto on_callback = [&num_notif](const json&) { ++num_notif; }; + auto on_subscribe = [&num_notif](const json&) { num_notif = 0; }; + auto on_unsubscribe = [&num_notif, &fin_number](const json&) { + fin_number = num_notif; + }; + int sub_id = sub.onSlotUpdate(on_callback, solana::Commitment::CONFIRMED, + on_subscribe, on_unsubscribe); + sleep(10); + CHECK_GT(num_notif, 0); + sub.removeSlotUpdateListener(sub_id); + sleep(10); + CHECK_EQ(num_notif, fin_number); +} + TEST_CASE("getTokenSupply") { const auto connection = solana::rpc::Connection(solana::MAINNET_BETA); const auto TokenSupply = @@ -1020,3 +1038,4 @@ TEST_CASE("getTokenAccountsByOwner") { solana::TokenAccountsByOwnerConfig{{}, "jsonParsed"}); CHECK_GT(TokenAccountsByOwner.value.size(), 0); } +