aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Michael Jurkoic <mjjurkoic@gmail.com>2024-03-17 14:36:41 -0500
committerLibravatar Michael Jurkoic <mjjurkoic@gmail.com>2024-03-17 14:36:41 -0500
commit423536e49259d338499dd8f8afaf106be7360764 (patch)
tree3a8dcbf74c792f2e6e3c67b43164370f24f6cba1
parent20b0f9c073d52e95b02399d6a243010e36b6c4f1 (diff)
Open relay subscriptions for a filter request
-rw-r--r--include/nostr.hpp18
-rw-r--r--src/nostr_service.cpp52
2 files changed, 67 insertions, 3 deletions
diff --git a/include/nostr.hpp b/include/nostr.hpp
index 8041efe..22d9956 100644
--- a/include/nostr.hpp
+++ b/include/nostr.hpp
@@ -142,12 +142,22 @@ public:
*/
std::tuple<RelayList, RelayList> publishEvent(Event event);
- // TODO: Add methods for reading events from relays.
+ /**
+ * @brief Queries all open relay connections for events matching the given set of filters.
+ * @returns A tuple of `RelayList` objects, of the form `<successes, failures>`, indicating
+ * to which relays the request was successfully sent, and which relays did not successfully
+ * receive the request.
+ */
+ std::tuple<RelayList, RelayList> queryRelays(Filters filters);
+
+ // TODO: Write a method that receives events for an active subscription.
+ // TODO: Write a method that closes active subscriptions.
private:
std::mutex _propertyMutex;
RelayList _defaultRelays;
RelayList _activeRelays;
+ std::unordered_map<std::string, std::vector<std::string>> _subscriptionIds;
client::IWebSocketClient* _client;
/**
@@ -182,5 +192,11 @@ private:
* @brief Closes the connection from the client to the given relay.
*/
void disconnect(std::string relay);
+
+ /**
+ * @brief Generates a unique subscription ID that may be used to identify event requests.
+ * @returns A stringified UUID.
+ */
+ std::string generateSubscriptionId();
};
} // namespace nostr
diff --git a/src/nostr_service.cpp b/src/nostr_service.cpp
index 4f4aadc..3025b96 100644
--- a/src/nostr_service.cpp
+++ b/src/nostr_service.cpp
@@ -1,3 +1,6 @@
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
#include <plog/Init.h>
#include <plog/Log.h>
#include <websocketpp/client.hpp>
@@ -7,6 +10,9 @@
#include "client/web_socket_client.hpp"
using std::async;
+using boost::uuids::random_generator;
+using boost::uuids::to_string;
+using boost::uuids::uuid;
using std::future;
using std::lock_guard;
using std::make_tuple;
@@ -104,8 +110,6 @@ void NostrService::closeRelayConnections(RelayList relays)
tuple<RelayList, RelayList> NostrService::publishEvent(Event event)
{
- // TODO: Add validation function.
-
RelayList successfulRelays;
RelayList failedRelays;
@@ -141,6 +145,44 @@ tuple<RelayList, RelayList> NostrService::publishEvent(Event event)
return make_tuple(successfulRelays, failedRelays);
};
+tuple<RelayList, RelayList> NostrService::queryRelays(Filters filters)
+{
+ RelayList successfulRelays;
+ RelayList failedRelays;
+
+ vector<future<tuple<string, bool>>> requestFutures;
+ for (const string relay : this->_activeRelays)
+ {
+ string subscriptionId = this->generateSubscriptionId();
+ this->_subscriptionIds[relay].push_back(subscriptionId);
+ string request = filters.serialize(subscriptionId);
+
+ future<tuple<string, bool>> requestFuture = async([this, &relay, &request]() {
+ return this->_client->send(request, relay);
+ });
+ requestFutures.push_back(move(requestFuture));
+ }
+
+ for (auto& publishFuture : requestFutures)
+ {
+ auto [relay, isSuccess] = publishFuture.get();
+ if (isSuccess)
+ {
+ successfulRelays.push_back(relay);
+ }
+ else
+ {
+ failedRelays.push_back(relay);
+ }
+ }
+
+ size_t targetCount = this->_activeRelays.size();
+ size_t successfulCount = successfulRelays.size();
+ PLOG_INFO << "Published event to " << successfulCount << "/" << targetCount << " target relays.";
+
+ return make_tuple(successfulRelays, failedRelays);
+};
+
RelayList NostrService::getConnectedRelays(RelayList relays)
{
PLOG_VERBOSE << "Identifying connected relays.";
@@ -245,4 +287,10 @@ void NostrService::disconnect(string relay)
lock_guard<mutex> lock(this->_propertyMutex);
this->eraseActiveRelay(relay);
};
+
+string NostrService::generateSubscriptionId()
+{
+ uuid uuid = random_generator()();
+ return to_string(uuid);
+};
} // namespace nostr