diff options
author | Michael J <37635304+buttercat1791@users.noreply.github.com> | 2024-03-03 11:56:37 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-03 11:56:37 -0600 |
commit | 0d87b4053983ec8edaff5b73491b717866876586 (patch) | |
tree | 915e73bdcce6d54558f1aea4bcf2ca2813b1d5a4 /include | |
parent | d02431d723f560f511aafa7e4b224046a4322021 (diff) |
Create Nostr Service and Add Write Capabilities (#1)v0.0.1
Diffstat (limited to 'include')
-rw-r--r-- | include/client/web_socket_client.hpp | 49 | ||||
-rw-r--r-- | include/nostr.hpp | 123 |
2 files changed, 172 insertions, 0 deletions
diff --git a/include/client/web_socket_client.hpp b/include/client/web_socket_client.hpp new file mode 100644 index 0000000..0f58749 --- /dev/null +++ b/include/client/web_socket_client.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include <string> + +namespace client +{ +/** + * @brief An interface for a WebSocket client singleton. + */ +class IWebSocketClient +{ +public: + /** + * @brief Starts the client. + * @remark This method must be called before any other client methods. + */ + virtual void start() = 0; + + /** + * @brief Stops the client. + * @remark This method should be called when the client is no longer needed, before it is + * destroyed. + */ + virtual void stop() = 0; + + /** + * @brief Opens a connection to the given server. + */ + virtual void openConnection(std::string uri) = 0; + + /** + * @brief Indicates whether the client is connected to the given server. + * @returns True if the client is connected, false otherwise. + */ + virtual bool isConnected(std::string uri) = 0; + + /** + * @brief Sends the given message to the given server. + * @returns A tuple indicating the server URI and whether the message was successfully + * sent. + */ + virtual std::tuple<std::string, bool> send(std::string message, std::string uri) = 0; + + /** + * @brief Closes the connection to the given server. + */ + virtual void closeConnection(std::string uri) = 0; +}; +} // namespace client diff --git a/include/nostr.hpp b/include/nostr.hpp new file mode 100644 index 0000000..47b56f9 --- /dev/null +++ b/include/nostr.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include <mutex> +#include <string> +#include <tuple> +#include <vector> + +#include <nlohmann/json.hpp> +#include <plog/Log.h> +#include <websocketpp/client.hpp> +#include <websocketpp/config/asio_client.hpp> + +#include "client/web_socket_client.hpp" + +namespace nostr +{ +typedef std::vector<std::string> RelayList; + +// TODO: Add null checking to seralization and deserialization methods. +/** + * @brief A Nostr event. + * @remark All data transmitted over the Nostr protocol is encoded in JSON blobs. This struct + * is common to every Nostr event kind. The significance of each event is determined by the + * `tags` and `content` fields. +*/ +struct Event +{ + std::string id; ///< SHA-256 hash of the event data. + std::string pubkey; ///< Public key of the event creator. + std::string created_at; ///< Unix timestamp of the event creation. + int kind; ///< Event kind. + std::vector<std::vector<std::string>> tags; ///< Arbitrary event metadata. + std::string content; ///< Event content. + std::string sig; ///< Event signature created with the private key of the event creator. + + nlohmann::json serialize() const; + void deserialize(std::string jsonString); +}; + +class NostrService +{ +public: + NostrService(plog::IAppender* appender, client::IWebSocketClient* client); + NostrService(plog::IAppender* appender, client::IWebSocketClient* client, RelayList relays); + ~NostrService(); + + RelayList defaultRelays() const; + + RelayList activeRelays() const; + + /** + * @brief Opens connections to the default Nostr relays of the instance, as specified in + * the constructor. + * @return A list of the relay URLs to which connections were successfully opened. + */ + RelayList openRelayConnections(); + + /** + * @brief Opens connections to the specified Nostr relays. + * @returns A list of the relay URLs to which connections were successfully opened. + */ + RelayList openRelayConnections(RelayList relays); + + /** + * @brief Closes all open relay connections. + */ + void closeRelayConnections(); + + /** + * @brief Closes any open connections to the specified Nostr relays. + */ + void closeRelayConnections(RelayList relays); + + /** + * @brief Publishes a Nostr event to all open relay connections. + * @returns A tuple of `RelayList` objects, of the form `<successes, failures>`, indicating + * to which relays the event was published successfully, and to which relays the event failed + * to publish. + */ + std::tuple<RelayList, RelayList> publishEvent(Event event); + + // TODO: Add methods for reading events from relays. + +private: + std::mutex _propertyMutex; + RelayList _defaultRelays; + RelayList _activeRelays; + client::IWebSocketClient* _client; + + /** + * @brief Determines which of the given relays are currently connected. + * @returns A list of the URIs of currently-open relay connections from the given list. + */ + RelayList getConnectedRelays(RelayList relays); + + /** + * @brief Determines which of the given relays are not currently connected. + * @returns A list of the URIs of currently-unconnected relays from the given list. + */ + RelayList getUnconnectedRelays(RelayList relays); + + /** + * @brief Determines whether the given relay is currently connected. + * @returns True if the relay is connected, false otherwise. + */ + bool isConnected(std::string relay); + + /** + * @brief Removes the given relay from the instance's list of active relays. + */ + void eraseActiveRelay(std::string relay); + + /** + * @brief Opens a connection from the client to the given relay. + */ + void connect(std::string relay); + + /** + * @brief Closes the connection from the client to the given relay. + */ + void disconnect(std::string relay); +}; +} // namespace nostr |