aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar buttercat1791 <mjjurkoic@gmail.com>2024-05-28 09:29:39 -0500
committerLibravatar buttercat1791 <mjjurkoic@gmail.com>2024-05-28 09:29:39 -0500
commit417383becd57e62108660c70872ac2024c1f29b2 (patch)
treec025eb80a36c9bf8aaf75e658d8d9b581fd3904b
parent9db92687fecd7528a6aa93e60bcbebc41342378c (diff)
Add connection token generation
-rw-r--r--include/signer/noscrypt_signer.hpp13
-rw-r--r--include/signer/signer.hpp23
-rw-r--r--src/signer/noscrypt_signer.cpp67
3 files changed, 78 insertions, 25 deletions
diff --git a/include/signer/noscrypt_signer.hpp b/include/signer/noscrypt_signer.hpp
index b4ea5f7..d2135da 100644
--- a/include/signer/noscrypt_signer.hpp
+++ b/include/signer/noscrypt_signer.hpp
@@ -26,8 +26,8 @@ public:
void receiveConnection(std::string connectionToken) override;
- void initiateConnection(
- std::string relay,
+ std::string initiateConnection(
+ std::vector<std::string> relays,
std::string name,
std::string url,
std::string description) override;
@@ -39,6 +39,9 @@ private:
std::string _localPrivateKey;
std::string _localPublicKey;
+
+ ///< A list of relays that will be used to connect to the remote signer.
+ std::vector<std::string> _relays;
/**
* @brief Initializes the noscrypt library context into the class's `context` property.
@@ -57,11 +60,11 @@ private:
#pragma region Logging
- void _logNoscryptInitResult(NCResult result);
+ void _logNoscryptInitResult(NCResult initResult);
- void _logNoscryptSecretKeyResult(NCResult result);
+ void _logNoscryptSecretValidationResult(NCResult secretValidationResult);
- void _logNoscryptPublicKeyResult(NCResult result);
+ void _logNoscryptPubkeyGenerationResult(NCResult pubkeyGenerationResult);
#pragma endregion
};
diff --git a/include/signer/signer.hpp b/include/signer/signer.hpp
index 319f739..c774d1d 100644
--- a/include/signer/signer.hpp
+++ b/include/signer/signer.hpp
@@ -2,6 +2,7 @@
#include <memory>
#include <string>
+#include <vector>
#include "data/data.hpp"
@@ -30,10 +31,28 @@ class INostrConnectSigner : public ISigner
public:
virtual ~INostrConnectSigner() = default;
+ /**
+ * @brief Establishes a connection to a remote signer using a connection token generated by the
+ * signer.
+ * @param connectionToken A connection token string beginning with `bunker://`, as defined by
+ * NIP-46.
+ * @remark A typical use case for this method would be for the user to paste a signer-generated
+ * connection token into a client application, which would then call this method to establish a
+ * connection to the remote signer.
+ */
virtual void receiveConnection(std::string connectionToken) = 0;
- virtual void initiateConnection(
- std::string relay,
+ /**
+ * @brief Generates a connection token that a remote signer may use to establish a connection
+ * to the client.
+ * @param relays A list of one or more relays the client will use to communicate with the
+ * remote signer.
+ * @returns A connection token string beginning with `nostrconnect://`, as specified by NIP-46,
+ * that may be provided to a remote signer to establish a connection to the client. Returns an
+ * empty string if the connection token generation fails.
+ */
+ virtual std::string initiateConnection(
+ std::vector<std::string> relays,
std::string name,
std::string url,
std::string description) = 0;
diff --git a/src/signer/noscrypt_signer.cpp b/src/signer/noscrypt_signer.cpp
index fa391d1..5d966ba 100644
--- a/src/signer/noscrypt_signer.cpp
+++ b/src/signer/noscrypt_signer.cpp
@@ -34,13 +34,44 @@ void nostr::signer::NoscryptSigner::receiveConnection(string connectionToken)
// Receive the connection token here.
};
-void nostr::signer::NoscryptSigner::initiateConnection(
- string relay,
+string nostr::signer::NoscryptSigner::initiateConnection(
+ vector<string> relays,
string name,
string url,
string description)
{
- // Initiate the connection here.
+ // Return an empty string if the local keypair is invalid.
+ if (this->_localPrivateKey.empty() || this->_localPublicKey.empty())
+ {
+ PLOG_ERROR << "A valid local keypair is required to connect to a remote signer.";
+ return string();
+ }
+
+ // Return an empty string if no relays are provided.
+ if (relays.empty())
+ {
+ PLOG_ERROR << "At least one relay must be provided to connect to a remote signer.";
+ return string();
+ }
+
+ // Store the provided relay list to be used for sending and receving connection events.
+ this->_relays = relays;
+
+ // Generate the connection token.
+ stringstream ss;
+ ss << "nostrconnect://" << this->_localPublicKey;
+ for (int i = 0; i < relays.size(); i++)
+ {
+ ss << (i == 0 ? "?" : "&");
+ ss << "relay=" << relays[i];
+ }
+ ss << "&metadata={";
+ ss << "\"name\":\"" << name << "\",";
+ ss << "\"url\":\"" << url << "\",";
+ ss << "\"description\":\"" << description << "\"";
+ ss << "}";
+
+ return ss.str();
};
void nostr::signer::NoscryptSigner::sign(shared_ptr<data::Event> event)
@@ -63,10 +94,10 @@ shared_ptr<NCContext> nostr::signer::NoscryptSigner::_initNoscryptContext()
uniform_int_distribution<> dist(0, contextStructSize);
generate_n(randomEntropy.get(), contextStructSize, [&]() { return dist(gen); });
- NCResult result = NCInitContext(context.get(), randomEntropy.get());
- this->_logNoscryptInitResult(result);
+ NCResult initResult = NCInitContext(context.get(), randomEntropy.get());
+ this->_logNoscryptInitResult(initResult);
- if (result != NC_SUCCESS)
+ if (initResult != NC_SUCCESS)
{
return nullptr;
}
@@ -95,10 +126,10 @@ tuple<string, string> nostr::signer::NoscryptSigner::_createLocalKeypair()
generate_n(secretKey.get()->key, NC_SEC_KEY_SIZE, [&]() { return dist(gen); });
// Check the validity of the secret key.
- NCResult result = NCValidateSecretKey(this->_noscryptContext.get(), secretKey.get());
- this->_logNoscryptSecretKeyResult(result);
+ NCResult secretValidationResult = NCValidateSecretKey(this->_noscryptContext.get(), secretKey.get());
+ this->_logNoscryptSecretValidationResult(secretValidationResult);
- if (result != NC_SUCCESS)
+ if (secretValidationResult != NC_SUCCESS)
{
// Return empty strings if the secret key generation fails.
return make_tuple(string(), string());
@@ -114,13 +145,13 @@ tuple<string, string> nostr::signer::NoscryptSigner::_createLocalKeypair()
// Use noscrypt to derive the public key from its private counterpart.
unique_ptr<NCPublicKey> pubkey(new NCPublicKey);
- NCResult result = NCGetPublicKey(
+ NCResult pubkeyGenerationResult = NCGetPublicKey(
this->_noscryptContext.get(),
secretKey.get(),
pubkey.get());
- this->_logNoscryptPublicKeyResult(result);
+ this->_logNoscryptPubkeyGenerationResult(pubkeyGenerationResult);
- if (result != NC_SUCCESS)
+ if (pubkeyGenerationResult != NC_SUCCESS)
{
// Return empty strings if the pubkey generation fails.
return make_tuple(string(), string());
@@ -140,9 +171,9 @@ tuple<string, string> nostr::signer::NoscryptSigner::_createLocalKeypair()
#pragma region Logging
-void nostr::signer::NoscryptSigner::_logNoscryptInitResult(NCResult result)
+void nostr::signer::NoscryptSigner::_logNoscryptInitResult(NCResult initResult)
{
- switch (result) {
+ switch (initResult) {
case NC_SUCCESS:
PLOG_INFO << "noscrypt - success";
break;
@@ -169,9 +200,9 @@ void nostr::signer::NoscryptSigner::_logNoscryptInitResult(NCResult result)
}
};
-void nostr::signer::NoscryptSigner::_logNoscryptSecretKeyResult(NCResult result)
+void nostr::signer::NoscryptSigner::_logNoscryptSecretValidationResult(NCResult secretValidationResult)
{
- switch (result) {
+ switch (secretValidationResult) {
case NC_SUCCESS:
PLOG_INFO << "noscrypt - success: Generated a valid secret key.";
break;
@@ -198,9 +229,9 @@ void nostr::signer::NoscryptSigner::_logNoscryptSecretKeyResult(NCResult result)
}
};
-void nostr::signer::NoscryptSigner::_logNoscryptPublicKeyResult(NCResult result)
+void nostr::signer::NoscryptSigner::_logNoscryptPubkeyGenerationResult(NCResult pubkeyGenerationResult)
{
- switch (result) {
+ switch (pubkeyGenerationResult) {
case NC_SUCCESS:
PLOG_INFO << "noscrypt - success: Generated a valid public key.";
break;