diff options
author | buttercat1791 <mjjurkoic@gmail.com> | 2024-05-26 12:31:12 -0500 |
---|---|---|
committer | buttercat1791 <mjjurkoic@gmail.com> | 2024-05-26 12:31:12 -0500 |
commit | 1d6b704c15ee289037447fb566e7583962496650 (patch) | |
tree | e1cd3322d4f30746c32e7f46e58060a66c5abc23 /src | |
parent | a7d3e3d2ce1797fc2b7fc918684777ae75adb822 (diff) |
Refactor to separate interface from implementation
Diffstat (limited to 'src')
-rw-r--r-- | src/client/websocketpp_client.cpp | 193 | ||||
-rw-r--r-- | src/data/event.cpp | 6 | ||||
-rw-r--r-- | src/nostr_service_base.cpp (renamed from src/nostr_service.cpp) | 119 | ||||
-rw-r--r-- | src/signer/noscrypt_signer.cpp | 274 |
4 files changed, 270 insertions, 322 deletions
diff --git a/src/client/websocketpp_client.cpp b/src/client/websocketpp_client.cpp index 9967d74..3cc6c99 100644 --- a/src/client/websocketpp_client.cpp +++ b/src/client/websocketpp_client.cpp @@ -1,132 +1,105 @@ -#include "web_socket_client.hpp" - -using std::error_code; -using std::function; -using std::lock_guard; -using std::make_tuple; -using std::mutex; -using std::string; -using std::tuple; -using std::unordered_map; - -namespace nostr -{ -namespace client -{ -/** - * @brief An implementation of the `IWebSocketClient` interface that uses the WebSocket++ library. - */ -class WebsocketppClient : public IWebSocketClient -{ -public: - void start() override - { - this->_client.init_asio(); - this->_client.start_perpetual(); - }; - - void stop() override - { - this->_client.stop_perpetual(); - this->_client.stop(); - }; +#include "websocketpp_client.hpp" - void openConnection(string uri) override - { - error_code error; - websocketpp_client::connection_ptr connection = this->_client.get_connection(uri, error); - - if (error.value() == -1) - { - // PLOG_ERROR << "Error connecting to relay " << relay << ": " << error.message(); - } +using namespace std; - // Configure the connection here via the connection pointer. - connection->set_fail_handler([this, uri](auto handle) { - // PLOG_ERROR << "Error connecting to relay " << relay << ": Handshake failed."; - lock_guard<mutex> lock(this->_propertyMutex); - if (this->isConnected(uri)) - { - this->_connectionHandles.erase(uri); - } - }); +void nostr::client::WebsocketppClient::start() +{ + this->_client.init_asio(); + this->_client.start_perpetual(); +}; - lock_guard<mutex> lock(this->_propertyMutex); - this->_connectionHandles[uri] = connection->get_handle(); - this->_client.connect(connection); - }; +void nostr::client::WebsocketppClient::stop() +{ + this->_client.stop_perpetual(); + this->_client.stop(); +}; - bool isConnected(string uri) override - { - lock_guard<mutex> lock(this->_propertyMutex); - return this->_connectionHandles.find(uri) != this->_connectionHandles.end(); - }; +void nostr::client::WebsocketppClient::openConnection(string uri) +{ + error_code error; + websocketpp_client::connection_ptr connection = this->_client.get_connection(uri, error); - tuple<string, bool> send(string message, string uri) override + if (error.value() == -1) { - error_code error; + // PLOG_ERROR << "Error connecting to relay " << relay << ": " << error.message(); + } - // Make sure the connection isn't closed from under us. + // Configure the connection here via the connection pointer. + connection->set_fail_handler([this, uri](auto handle) { + // PLOG_ERROR << "Error connecting to relay " << relay << ": Handshake failed."; lock_guard<mutex> lock(this->_propertyMutex); - this->_client.send( - this->_connectionHandles[uri], - message, - websocketpp::frame::opcode::text, - error); - - if (error.value() == -1) + if (this->isConnected(uri)) { - return make_tuple(uri, false); + this->_connectionHandles.erase(uri); } + }); - return make_tuple(uri, true); - }; + lock_guard<mutex> lock(this->_propertyMutex); + this->_connectionHandles[uri] = connection->get_handle(); + this->_client.connect(connection); +}; - tuple<string, bool> send(string message, string uri, function<void(const string&)> messageHandler) override - { - auto successes = this->send(message, uri); - this->receive(uri, messageHandler); - return successes; - }; +bool nostr::client::WebsocketppClient::isConnected(string uri) +{ + lock_guard<mutex> lock(this->_propertyMutex); + return this->_connectionHandles.find(uri) != this->_connectionHandles.end(); +}; - void receive(string uri, function<void(const string&)> messageHandler) override - { - lock_guard<mutex> lock(this->_propertyMutex); - auto connectionHandle = this->_connectionHandles[uri]; - auto connection = this->_client.get_con_from_hdl(connectionHandle); +tuple<string, bool> nostr::client::WebsocketppClient::send(string message, string uri) +{ + error_code error; - connection->set_message_handler([messageHandler]( - websocketpp::connection_hdl connectionHandle, - websocketpp_client::message_ptr message) - { - messageHandler(message->get_payload()); - }); - }; + // Make sure the connection isn't closed from under us. + lock_guard<mutex> lock(this->_propertyMutex); + this->_client.send( + this->_connectionHandles[uri], + message, + websocketpp::frame::opcode::text, + error); - void closeConnection(string uri) override + if (error.value() == -1) { - lock_guard<mutex> lock(this->_propertyMutex); + return make_tuple(uri, false); + } - websocketpp::connection_hdl handle = this->_connectionHandles[uri]; - this->_client.close( - handle, - websocketpp::close::status::going_away, - "_client requested close."); - - this->_connectionHandles.erase(uri); - }; + return make_tuple(uri, true); +}; -private: - typedef websocketpp::client<websocketpp::config::asio_client> websocketpp_client; - typedef unordered_map<string, websocketpp::connection_hdl>::iterator connection_hdl_iterator; +tuple<string, bool> nostr::client::WebsocketppClient::send( + string message, + string uri, + function<void(const string&)> messageHandler) +{ + auto successes = this->send(message, uri); + this->receive(uri, messageHandler); + return successes; +}; - websocketpp_client _client; - unordered_map<string, websocketpp::connection_hdl> _connectionHandles; - mutex _propertyMutex; +void nostr::client::WebsocketppClient::receive( + string uri, + function<void(const string&)> messageHandler) +{ + lock_guard<mutex> lock(this->_propertyMutex); + auto connectionHandle = this->_connectionHandles[uri]; + auto connection = this->_client.get_con_from_hdl(connectionHandle); - void onMessage(websocketpp::connection_hdl handle, websocketpp_client::message_ptr message) + connection->set_message_handler([messageHandler]( + websocketpp::connection_hdl connectionHandle, + websocketpp_client::message_ptr message) { - }; + messageHandler(message->get_payload()); + }); +}; + +void nostr::client::WebsocketppClient::closeConnection(string uri) +{ + lock_guard<mutex> lock(this->_propertyMutex); + + websocketpp::connection_hdl handle = this->_connectionHandles[uri]; + this->_client.close( + handle, + websocketpp::close::status::going_away, + "_client requested close."); + + this->_connectionHandles.erase(uri); }; -} // namespace client -} // namespace nostr diff --git a/src/data/event.cpp b/src/data/event.cpp index 620ee3f..5f611ff 100644 --- a/src/data/event.cpp +++ b/src/data/event.cpp @@ -88,12 +88,6 @@ void Event::validate() { throw std::invalid_argument("Event::validate: A valid event kind is required."); } - - bool hasSignature = this->sig.length() > 0; - if (!hasSignature) - { - throw std::invalid_argument("Event::validate: The event must be signed."); - } }; string Event::generateId(string serializedData) const diff --git a/src/nostr_service.cpp b/src/nostr_service_base.cpp index 9f6b8ce..bce6728 100644 --- a/src/nostr_service.cpp +++ b/src/nostr_service_base.cpp @@ -1,53 +1,52 @@ -#include "nostr.hpp" +#include "nostr_service_base.hpp" using namespace nlohmann; using namespace std; -namespace nostr -{ -NostrService::NostrService( +nostr::NostrServiceBase::NostrServiceBase( shared_ptr<plog::IAppender> appender, - shared_ptr<client::IWebSocketClient> client, - shared_ptr<signer::ISigner> signer) -: NostrService(appender, client, signer, {}) { }; + shared_ptr<client::IWebSocketClient> client) +: NostrServiceBase(appender, client, {}) { }; -NostrService::NostrService( +nostr::NostrServiceBase::NostrServiceBase( shared_ptr<plog::IAppender> appender, shared_ptr<client::IWebSocketClient> client, - shared_ptr<signer::ISigner> signer, vector<string> relays) -: _defaultRelays(relays), _client(client), _signer(signer) +: _defaultRelays(relays), _client(client) { plog::init(plog::debug, appender.get()); client->start(); }; -NostrService::~NostrService() +nostr::NostrServiceBase::~NostrServiceBase() { this->_client->stop(); }; -vector<string> NostrService::defaultRelays() const { return this->_defaultRelays; }; +vector<string> nostr::NostrServiceBase::defaultRelays() const +{ return this->_defaultRelays; }; -vector<string> NostrService::activeRelays() const { return this->_activeRelays; }; +vector<string> nostr::NostrServiceBase::activeRelays() const +{ return this->_activeRelays; }; -unordered_map<string, vector<string>> NostrService::subscriptions() const { return this->_subscriptions; }; +unordered_map<string, vector<string>> nostr::NostrServiceBase::subscriptions() const +{ return this->_subscriptions; }; -vector<string> NostrService::openRelayConnections() +vector<string> nostr::NostrServiceBase::openRelayConnections() { return this->openRelayConnections(this->_defaultRelays); }; -vector<string> NostrService::openRelayConnections(vector<string> relays) +vector<string> nostr::NostrServiceBase::openRelayConnections(vector<string> relays) { PLOG_INFO << "Attempting to connect to Nostr relays."; - vector<string> unconnectedRelays = this->getUnconnectedRelays(relays); + vector<string> unconnectedRelays = this->_getUnconnectedRelays(relays); vector<thread> connectionThreads; for (string relay : unconnectedRelays) { thread connectionThread([this, relay]() { - this->connect(relay); + this->_connect(relay); }); connectionThreads.push_back(move(connectionThread)); } @@ -65,7 +64,7 @@ vector<string> NostrService::openRelayConnections(vector<string> relays) return this->_activeRelays; }; -void NostrService::closeRelayConnections() +void nostr::NostrServiceBase::closeRelayConnections() { if (this->_activeRelays.size() == 0) { @@ -76,16 +75,16 @@ void NostrService::closeRelayConnections() this->closeRelayConnections(this->_activeRelays); }; -void NostrService::closeRelayConnections(vector<string> relays) +void nostr::NostrServiceBase::closeRelayConnections(vector<string> relays) { PLOG_INFO << "Disconnecting from Nostr relays."; - vector<string> connectedRelays = getConnectedRelays(relays); + vector<string> connectedRelays = this->_getConnectedRelays(relays); vector<thread> disconnectionThreads; for (string relay : connectedRelays) { thread disconnectionThread([this, relay]() { - this->disconnect(relay); + this->_disconnect(relay); }); disconnectionThreads.push_back(move(disconnectionThread)); @@ -101,7 +100,8 @@ void NostrService::closeRelayConnections(vector<string> relays) }; // TODO: Make this method return a promise. -tuple<vector<string>, vector<string>> NostrService::publishEvent(shared_ptr<data::Event> event) +tuple<vector<string>, vector<string>> nostr::NostrServiceBase::publishEvent( + shared_ptr<nostr::data::Event> event) { vector<string> successfulRelays; vector<string> failedRelays; @@ -111,7 +111,6 @@ tuple<vector<string>, vector<string>> NostrService::publishEvent(shared_ptr<data json message; try { - this->_signer->sign(event); message = json::array({ "EVENT", event->serialize() }); } catch (const std::invalid_argument& e) @@ -138,7 +137,7 @@ tuple<vector<string>, vector<string>> NostrService::publishEvent(shared_ptr<data relay, [this, &relay, &event, &publishPromise](string response) { - this->onAcceptance(response, [this, &relay, &event, &publishPromise](bool isAccepted) + this->_onAcceptance(response, [this, &relay, &event, &publishPromise](bool isAccepted) { if (isAccepted) { @@ -182,7 +181,8 @@ tuple<vector<string>, vector<string>> NostrService::publishEvent(shared_ptr<data // TODO: Make this method return a promise. // TODO: Add a timeout to this method to prevent hanging while waiting for the relay. -vector<shared_ptr<data::Event>> NostrService::queryRelays(shared_ptr<data::Filters> filters) +vector<shared_ptr<nostr::data::Event>> nostr::NostrServiceBase::queryRelays( + shared_ptr<nostr::data::Filters> filters) { if (filters->limit > 64 || filters->limit < 1) { @@ -190,9 +190,9 @@ vector<shared_ptr<data::Event>> NostrService::queryRelays(shared_ptr<data::Filte filters->limit = 16; } - vector<shared_ptr<data::Event>> events; + vector<shared_ptr<nostr::data::Event>> events; - string subscriptionId = this->generateSubscriptionId(); + string subscriptionId = this->_generateSubscriptionId(); string request; try @@ -226,9 +226,9 @@ vector<shared_ptr<data::Event>> NostrService::queryRelays(shared_ptr<data::Filte relay, [this, &relay, &events, &eosePromise](string payload) { - this->onSubscriptionMessage( + this->_onSubscriptionMessage( payload, - [&events](const string&, shared_ptr<data::Event> event) + [&events](const string&, shared_ptr<nostr::data::Event> event) { events.push_back(event); }, @@ -276,16 +276,16 @@ vector<shared_ptr<data::Event>> NostrService::queryRelays(shared_ptr<data::Filte return events; }; -string NostrService::queryRelays( - shared_ptr<data::Filters> filters, - function<void(const string&, shared_ptr<data::Event>)> eventHandler, +string nostr::NostrServiceBase::queryRelays( + shared_ptr<nostr::data::Filters> filters, + function<void(const string&, shared_ptr<nostr::data::Event>)> eventHandler, function<void(const string&)> eoseHandler, function<void(const string&, const string&)> closeHandler) { vector<string> successfulRelays; vector<string> failedRelays; - string subscriptionId = this->generateSubscriptionId(); + string subscriptionId = this->_generateSubscriptionId(); string request = filters->serialize(subscriptionId); vector<future<tuple<string, bool>>> requestFutures; for (const string relay : this->_activeRelays) @@ -302,7 +302,7 @@ string NostrService::queryRelays( relay, [this, &eventHandler, &eoseHandler, &closeHandler](string payload) { - this->onSubscriptionMessage(payload, eventHandler, eoseHandler, closeHandler); + this->_onSubscriptionMessage(payload, eventHandler, eoseHandler, closeHandler); }); }); requestFutures.push_back(move(requestFuture)); @@ -328,7 +328,7 @@ string NostrService::queryRelays( return subscriptionId; }; -tuple<vector<string>, vector<string>> NostrService::closeSubscription(string subscriptionId) +tuple<vector<string>, vector<string>> nostr::NostrServiceBase::closeSubscription(string subscriptionId) { vector<string> successfulRelays; vector<string> failedRelays; @@ -388,21 +388,21 @@ tuple<vector<string>, vector<string>> NostrService::closeSubscription(string sub return make_tuple(successfulRelays, failedRelays); }; -bool NostrService::closeSubscription(string subscriptionId, string relay) +bool nostr::NostrServiceBase::closeSubscription(string subscriptionId, string relay) { - if (!this->hasSubscription(subscriptionId, relay)) + if (!this->_hasSubscription(subscriptionId, relay)) { PLOG_WARNING << "Subscription " << subscriptionId << " not found on relay " << relay; return false; } - if (!this->isConnected(relay)) + if (!this->_isConnected(relay)) { PLOG_WARNING << "Relay " << relay << " is not connected."; return false; } - string request = this->generateCloseRequest(subscriptionId); + string request = this->_generateCloseRequest(subscriptionId); auto [uri, success] = this->_client->send(request, relay); if (success) @@ -428,7 +428,7 @@ bool NostrService::closeSubscription(string subscriptionId, string relay) return success; }; -vector<string> NostrService::closeSubscriptions() +vector<string> nostr::NostrServiceBase::closeSubscriptions() { unique_lock<mutex> lock(this->_propertyMutex); vector<string> subscriptionIds; @@ -451,7 +451,7 @@ vector<string> NostrService::closeSubscriptions() return remainingSubscriptions; }; -vector<string> NostrService::getConnectedRelays(vector<string> relays) +vector<string> nostr::NostrServiceBase::_getConnectedRelays(vector<string> relays) { PLOG_VERBOSE << "Identifying connected relays."; vector<string> connectedRelays; @@ -468,7 +468,7 @@ vector<string> NostrService::getConnectedRelays(vector<string> relays) } else if (isActive && !isConnected) { - this->eraseActiveRelay(relay); + this->_eraseActiveRelay(relay); } else if (!isActive && isConnected) { @@ -479,7 +479,7 @@ vector<string> NostrService::getConnectedRelays(vector<string> relays) return connectedRelays; }; -vector<string> NostrService::getUnconnectedRelays(vector<string> relays) +vector<string> nostr::NostrServiceBase::_getUnconnectedRelays(vector<string> relays) { PLOG_VERBOSE << "Identifying unconnected relays."; vector<string> unconnectedRelays; @@ -498,7 +498,7 @@ vector<string> NostrService::getUnconnectedRelays(vector<string> relays) else if (isActive && !isConnected) { PLOG_VERBOSE << "Relay " << relay << " is active but not connected. Removing from active relays list."; - this->eraseActiveRelay(relay); + this->_eraseActiveRelay(relay); unconnectedRelays.push_back(relay); } else if (!isActive && isConnected) @@ -510,7 +510,7 @@ vector<string> NostrService::getUnconnectedRelays(vector<string> relays) return unconnectedRelays; }; -bool NostrService::isConnected(string relay) +bool nostr::NostrServiceBase::_isConnected(string relay) { auto it = find(this->_activeRelays.begin(), this->_activeRelays.end(), relay); if (it != this->_activeRelays.end()) // If the relay is in this->_activeRelays @@ -520,7 +520,7 @@ bool NostrService::isConnected(string relay) return false; }; -void NostrService::eraseActiveRelay(string relay) +void nostr::NostrServiceBase::_eraseActiveRelay(string relay) { auto it = find(this->_activeRelays.begin(), this->_activeRelays.end(), relay); if (it != this->_activeRelays.end()) // If the relay is in this->_activeRelays @@ -529,7 +529,7 @@ void NostrService::eraseActiveRelay(string relay) } }; -void NostrService::connect(string relay) +void nostr::NostrServiceBase::_connect(string relay) { PLOG_VERBOSE << "Connecting to relay " << relay; this->_client->openConnection(relay); @@ -548,28 +548,28 @@ void NostrService::connect(string relay) } }; -void NostrService::disconnect(string relay) +void nostr::NostrServiceBase::_disconnect(string relay) { this->_client->closeConnection(relay); lock_guard<mutex> lock(this->_propertyMutex); - this->eraseActiveRelay(relay); + this->_eraseActiveRelay(relay); }; -string NostrService::generateSubscriptionId() +string nostr::NostrServiceBase::_generateSubscriptionId() { UUIDv4::UUIDGenerator<std::mt19937_64> uuidGenerator; UUIDv4::UUID uuid = uuidGenerator.getUUID(); return uuid.str(); }; -string NostrService::generateCloseRequest(string subscriptionId) +string nostr::NostrServiceBase::_generateCloseRequest(string subscriptionId) { json jarr = json::array({ "CLOSE", subscriptionId }); return jarr.dump(); }; -bool NostrService::hasSubscription(string subscriptionId) +bool nostr::NostrServiceBase::_hasSubscription(string subscriptionId) { lock_guard<mutex> lock(this->_propertyMutex); auto it = this->_subscriptions.find(subscriptionId); @@ -577,7 +577,7 @@ bool NostrService::hasSubscription(string subscriptionId) return it != this->_subscriptions.end(); }; -bool NostrService::hasSubscription(string subscriptionId, string relay) +bool nostr::NostrServiceBase::_hasSubscription(string subscriptionId, string relay) { lock_guard<mutex> lock(this->_propertyMutex); auto subscriptionIt = this->_subscriptions.find(subscriptionId); @@ -593,9 +593,9 @@ bool NostrService::hasSubscription(string subscriptionId, string relay) return relayIt != relays.end(); }; -void NostrService::onSubscriptionMessage( +void nostr::NostrServiceBase::_onSubscriptionMessage( string message, - function<void(const string&, shared_ptr<data::Event>)> eventHandler, + function<void(const string&, shared_ptr<nostr::data::Event>)> eventHandler, function<void(const string&)> eoseHandler, function<void(const string&, const string&)> closeHandler) { @@ -606,8 +606,8 @@ void NostrService::onSubscriptionMessage( if (messageType == "EVENT") { string subscriptionId = jMessage.at(1); - data::Event event = data::Event::fromString(jMessage.at(2)); - eventHandler(subscriptionId, make_shared<data::Event>(event)); + nostr::data::Event event = nostr::data::Event::fromString(jMessage.at(2)); + eventHandler(subscriptionId, make_shared<nostr::data::Event>(event)); } else if (messageType == "EOSE") { @@ -638,7 +638,7 @@ void NostrService::onSubscriptionMessage( } }; -void NostrService::onAcceptance(string message, function<void(const bool)> acceptanceHandler) +void nostr::NostrServiceBase::_onAcceptance(string message, function<void(const bool)> acceptanceHandler) { try { @@ -656,4 +656,3 @@ void NostrService::onAcceptance(string message, function<void(const bool)> accep throw je; } }; -} // namespace nostr diff --git a/src/signer/noscrypt_signer.cpp b/src/signer/noscrypt_signer.cpp index c56070c..39bb667 100644 --- a/src/signer/noscrypt_signer.cpp +++ b/src/signer/noscrypt_signer.cpp @@ -1,169 +1,151 @@ -#include <noscrypt.h> - -#include "signer.hpp" +#include "noscrypt_signer.hpp" using namespace std; -namespace nostr +nostr::signer::NoscryptSigner::NoscryptSigner(shared_ptr<plog::IAppender> appender) { -namespace signer + plog::init(plog::debug, appender.get()); + + this->noscryptContext = this->_initNoscryptContext(); + if (this->noscryptContext == nullptr) + { + return; + } + + const auto [privateKey, publicKey] = this->_createLocalKeypair(); + this->localPrivateKey = privateKey; + this->localPublicKey = publicKey; +}; + +nostr::signer::NoscryptSigner::~NoscryptSigner() { -class NoscryptSigner : public INostrConnectSigner + NCDestroyContext(this->noscryptContext.get()); +}; + +void nostr::signer::NoscryptSigner::receiveConnection(string connectionToken) { -public: - NoscryptSigner(shared_ptr<plog::IAppender> appender) - { - plog::init(plog::debug, appender.get()); + // Receive the connection token here. +}; - this->noscryptContext = this->initNoscryptContext(); - if (this->noscryptContext == nullptr) - { - return; - } +void nostr::signer::NoscryptSigner::initiateConnection( + string relay, + string name, + string url, + string description) +{ + // Initiate the connection here. +}; - const auto [privateKey, publicKey] = this->createLocalKeypair(); - this->localPrivateKey = privateKey; - this->localPublicKey = publicKey; - }; +void nostr::signer::NoscryptSigner::sign(shared_ptr<data::Event> event) +{ + // Sign the event here. +}; - ~NoscryptSigner() - { - NCDestroyContext(this->noscryptContext.get()); - }; +/** + * @brief Initializes the noscrypt library context into the class's `context` property. + * @returns `true` if successful, `false` otherwise. + */ +shared_ptr<NCContext> nostr::signer::NoscryptSigner::_initNoscryptContext() +{ + shared_ptr<NCContext> context(new NCContext); + auto contextStructSize = NCGetContextStructSize(); + unique_ptr<uint8_t> randomEntropy(new uint8_t[contextStructSize]); - void receiveConnection(string connectionToken) override - { - // Receive the connection token here. - }; - - void initiateConnection( - string relay, - string name, - string url, - string description) override - { - // Initiate the connection here. - }; + random_device rd; + mt19937 gen(rd()); + uniform_int_distribution<> dist(0, contextStructSize); + generate_n(randomEntropy.get(), contextStructSize, [&]() { return dist(gen); }); - void sign(shared_ptr<data::Event> event) override + NCResult result = NCInitContext(context.get(), randomEntropy.get()); + this->_logNoscryptResult(result); + + if (result != NC_SUCCESS) { - // Sign the event here. - }; + return nullptr; + } -private: - shared_ptr<NCContext> noscryptContext; + return context; +}; - string localPrivateKey; - string localPublicKey; +void nostr::signer::NoscryptSigner::_logNoscryptResult(NCResult result) +{ + switch (result) { + case NC_SUCCESS: + PLOG_INFO << "noscrypt - success"; + break; - /** - * @brief Initializes the noscrypt library context into the class's `context` property. - * @returns `true` if successful, `false` otherwise. - */ - shared_ptr<NCContext> initNoscryptContext() - { - shared_ptr<NCContext> context(new NCContext); - auto contextStructSize = NCGetContextStructSize(); - unique_ptr<uint8_t> randomEntropy(new uint8_t[contextStructSize]); + case E_NULL_PTR: + PLOG_ERROR << "noscrypt - error: A null pointer was passed to the initializer."; + break; - random_device rd; - mt19937 gen(rd()); - uniform_int_distribution<> dist(0, contextStructSize); - generate_n(randomEntropy.get(), contextStructSize, [&]() { return dist(gen); }); + case E_INVALID_ARG: + PLOG_ERROR << "noscrypt - error: An invalid argument was passed to the initializer."; + break; + + case E_INVALID_CONTEXT: + PLOG_ERROR << "noscrypt - error: The NCContext struct is in an invalid state."; + break; + + case E_ARGUMENT_OUT_OF_RANGE: + PLOG_ERROR << "noscrypt - error: An initializer argument was outside the range of acceptable values."; + break; + + case E_OPERATION_FAILED: + PLOG_ERROR << "noscrypt - error"; + break; + } +}; - NCResult result = NCInitContext(context.get(), randomEntropy.get()); - this->logNoscryptResult(result); +/** + * @brief Generates a private/public key pair for local use. + * @returns The generated keypair of the form `[privateKey, publicKey]`, or a pair of empty + * strings if the function failed. + * @remarks This keypair is intended for temporary use, and should not be saved or used outside + * of this class. + */ +tuple<string, string> nostr::signer::NoscryptSigner::_createLocalKeypair() +{ + string privateKey; + string publicKey; - if (result != NC_SUCCESS) - { - return nullptr; - } + // To generate a private key, all we need is a random 32-bit buffer. + unique_ptr<NCSecretKey> secretKey(new NCSecretKey); - return context; - }; + random_device rd; + mt19937 gen(rd()); + uniform_int_distribution<> dist(0, NC_SEC_KEY_SIZE); + generate_n(secretKey.get()->key, NC_SEC_KEY_SIZE, [&]() { return dist(gen); }); - void logNoscryptResult(NCResult result) + // Convert the buffer into a hex string for a more human-friendly representation. + stringstream secretKeyStream; + for (int i = 0; i < NC_SEC_KEY_SIZE; i++) + { + secretKeyStream << hex << setw(2) << setfill('0') << static_cast<int>(secretKey->key[i]); + } + privateKey = secretKeyStream.str(); + + // Use noscrypt to derive the public key from its private counterpart. + unique_ptr<NCPublicKey> pubkey(new NCPublicKey); + NCResult result = NCGetPublicKey( + this->noscryptContext.get(), + secretKey.get(), + pubkey.get()); + this->_logNoscryptResult(result); + + if (result != NC_SUCCESS) { - switch (result) { - case NC_SUCCESS: - PLOG_INFO << "noscrypt - success"; - break; - - case E_NULL_PTR: - PLOG_ERROR << "noscrypt - error: A null pointer was passed to the initializer."; - break; - - case E_INVALID_ARG: - PLOG_ERROR << "noscrypt - error: An invalid argument was passed to the initializer."; - break; - - case E_INVALID_CONTEXT: - PLOG_ERROR << "noscrypt - error: The NCContext struct is in an invalid state."; - break; - - case E_ARGUMENT_OUT_OF_RANGE: - PLOG_ERROR << "noscrypt - error: An initializer argument was outside the range of acceptable values."; - break; - - case E_OPERATION_FAILED: - PLOG_ERROR << "noscrypt - error"; - break; - } - }; - - /** - * @brief Generates a private/public key pair for local use. - * @returns The generated keypair of the form `[privateKey, publicKey]`, or a pair of empty - * strings if the function failed. - * @remarks This keypair is intended for temporary use, and should not be saved or used outside - * of this class. - */ - tuple<string, string> createLocalKeypair() + // Return empty strings if the key generation fails. + return make_tuple(string(), string()); + } + + // Convert the now-populated pubkey buffer into a hex string for the pubkey representation + // used by Nostr events. + stringstream pubkeyStream; + for (int i = 0; i < NC_SEC_KEY_SIZE; i++) { - string privateKey; - string publicKey; - - // To generate a private key, all we need is a random 32-bit buffer. - unique_ptr<NCSecretKey> secretKey(new NCSecretKey); - - random_device rd; - mt19937 gen(rd()); - uniform_int_distribution<> dist(0, NC_SEC_KEY_SIZE); - generate_n(secretKey.get()->key, NC_SEC_KEY_SIZE, [&]() { return dist(gen); }); - - // Convert the buffer into a hex string for a more human-friendly representation. - stringstream secretKeyStream; - for (int i = 0; i < NC_SEC_KEY_SIZE; i++) - { - secretKeyStream << hex << setw(2) << setfill('0') << static_cast<int>(secretKey->key[i]); - } - privateKey = secretKeyStream.str(); - - // Use noscrypt to derive the public key from its private counterpart. - unique_ptr<NCPublicKey> pubkey(new NCPublicKey); - NCResult result = NCGetPublicKey( - this->noscryptContext.get(), - secretKey.get(), - pubkey.get()); - this->logNoscryptResult(result); - - if (result != NC_SUCCESS) - { - // Return empty strings if the key generation fails. - return make_tuple(string(), string()); - } - - // Convert the now-populated pubkey buffer into a hex string for the pubkey representation - // used by Nostr events. - stringstream pubkeyStream; - for (int i = 0; i < NC_SEC_KEY_SIZE; i++) - { - pubkeyStream << hex << setw(2) << setfill('0') << static_cast<int>(pubkey->key[i]); - } - publicKey = pubkeyStream.str(); - - return make_tuple(privateKey, publicKey); - }; + pubkeyStream << hex << setw(2) << setfill('0') << static_cast<int>(pubkey->key[i]); + } + publicKey = pubkeyStream.str(); + + return make_tuple(privateKey, publicKey); }; -} // namespace signer -} // namespace nostr |