v0.1.13 - Fix Kind 23458 test script: use websocat for bidirectional relay communication and correct nak decrypt flag (-p instead of --recipient-pubkey). Admin command system now fully functional end-to-end with NIP-44 encryption.

This commit is contained in:
Your Name
2025-12-11 14:28:33 -04:00
parent 6592c37c6e
commit 4f1fbee52c
15 changed files with 3585 additions and 23 deletions

View File

@@ -5,6 +5,7 @@
*/
#include "relay_client.h"
#include "admin_commands.h"
#include "../nostr_core_lib/nostr_core/nostr_core.h"
#include <sqlite3.h>
#include <stdio.h>
@@ -529,7 +530,7 @@ int relay_client_publish_kind10002(void) {
}
}
// Send Kind 23457 admin response event
// Send Kind 23459 admin response event
int relay_client_send_admin_response(const char *recipient_pubkey, const char *response_content) {
if (!g_relay_state.enabled || !g_relay_state.running || !g_relay_state.pool) {
return -1;
@@ -539,7 +540,7 @@ int relay_client_send_admin_response(const char *recipient_pubkey, const char *r
return -1;
}
app_log(LOG_INFO, "Sending Kind 23457 admin response to %s", recipient_pubkey);
app_log(LOG_INFO, "Sending Kind 23459 admin response to %s", recipient_pubkey);
// TODO: Encrypt response_content using NIP-44
// For now, use plaintext (stub implementation)
@@ -560,9 +561,9 @@ int relay_client_send_admin_response(const char *recipient_pubkey, const char *r
return -1;
}
// Create and sign Kind 23457 event
// Create and sign Kind 23459 event
cJSON* event = nostr_create_and_sign_event(
23457, // kind
23459, // kind
encrypted_content, // content
tags, // tags
privkey_bytes, // private key
@@ -572,7 +573,7 @@ int relay_client_send_admin_response(const char *recipient_pubkey, const char *r
cJSON_Delete(tags);
if (!event) {
app_log(LOG_ERROR, "Failed to create Kind 23457 event");
app_log(LOG_ERROR, "Failed to create Kind 23459 event");
return -1;
}
@@ -583,16 +584,16 @@ int relay_client_send_admin_response(const char *recipient_pubkey, const char *r
g_relay_state.relay_count,
event,
on_publish_response,
(void*)"Kind 23457" // user_data to identify event type
(void*)"Kind 23459" // user_data to identify event type
);
cJSON_Delete(event);
if (result == 0) {
app_log(LOG_INFO, "Kind 23457 admin response publish initiated");
app_log(LOG_INFO, "Kind 23459 admin response publish initiated");
return 0;
} else {
app_log(LOG_ERROR, "Failed to initiate Kind 23457 admin response publish");
app_log(LOG_ERROR, "Failed to initiate Kind 23459 admin response publish");
return -1;
}
}
@@ -610,11 +611,11 @@ static void on_publish_response(const char* relay_url, const char* event_id, int
}
}
// Callback for received Kind 23456 admin command events
// Callback for received Kind 23458 admin command events
static void on_admin_command_event(cJSON* event, const char* relay_url, void* user_data) {
(void)user_data;
app_log(LOG_INFO, "Received Kind 23456 admin command from relay: %s", relay_url);
app_log(LOG_INFO, "Received Kind 23458 admin command from relay: %s", relay_url);
// Extract event fields
cJSON* kind_json = cJSON_GetObjectItem(event, "kind");
@@ -632,7 +633,7 @@ static void on_admin_command_event(cJSON* event, const char* relay_url, void* us
const char* encrypted_content = cJSON_GetStringValue(content_json);
const char* event_id = cJSON_GetStringValue(id_json);
if (kind != 23456) {
if (kind != 23458) {
app_log(LOG_WARN, "Unexpected event kind: %d", kind);
return;
}
@@ -645,12 +646,98 @@ static void on_admin_command_event(cJSON* event, const char* relay_url, void* us
app_log(LOG_INFO, "Processing admin command (event ID: %s)", event_id);
// TODO: Decrypt content using NIP-44
// For now, log the encrypted content
app_log(LOG_DEBUG, "Encrypted command content: %s", encrypted_content);
// Convert keys from hex to bytes
unsigned char server_privkey[32];
unsigned char admin_pubkey_bytes[32];
// TODO: Parse and execute command
// TODO: Send response using relay_client_send_admin_response()
if (nostr_hex_to_bytes(g_blossom_seckey, server_privkey, 32) != 0) {
app_log(LOG_ERROR, "Failed to convert server private key from hex");
return;
}
if (nostr_hex_to_bytes(sender_pubkey, admin_pubkey_bytes, 32) != 0) {
app_log(LOG_ERROR, "Failed to convert admin public key from hex");
return;
}
// Decrypt command content using NIP-44
char decrypted_command[4096];
if (admin_decrypt_command(server_privkey, admin_pubkey_bytes, encrypted_content,
decrypted_command, sizeof(decrypted_command)) != 0) {
app_log(LOG_ERROR, "Failed to decrypt admin command");
// Send error response
cJSON* error_response = cJSON_CreateObject();
cJSON_AddStringToObject(error_response, "status", "error");
cJSON_AddStringToObject(error_response, "message", "Failed to decrypt command");
char* error_json = cJSON_PrintUnformatted(error_response);
cJSON_Delete(error_response);
char encrypted_response[4096];
if (admin_encrypt_response(server_privkey, admin_pubkey_bytes, error_json,
encrypted_response, sizeof(encrypted_response)) == 0) {
relay_client_send_admin_response(sender_pubkey, encrypted_response);
}
free(error_json);
return;
}
app_log(LOG_DEBUG, "Decrypted command: %s", decrypted_command);
// Parse command JSON
cJSON* command_json = cJSON_Parse(decrypted_command);
if (!command_json) {
app_log(LOG_ERROR, "Failed to parse command JSON");
cJSON* error_response = cJSON_CreateObject();
cJSON_AddStringToObject(error_response, "status", "error");
cJSON_AddStringToObject(error_response, "message", "Invalid JSON format");
char* error_json = cJSON_PrintUnformatted(error_response);
cJSON_Delete(error_response);
char encrypted_response[4096];
if (admin_encrypt_response(server_privkey, admin_pubkey_bytes, error_json,
encrypted_response, sizeof(encrypted_response)) == 0) {
relay_client_send_admin_response(sender_pubkey, encrypted_response);
}
free(error_json);
return;
}
// Process command and get response
cJSON* response_json = admin_commands_process(command_json, event_id);
cJSON_Delete(command_json);
if (!response_json) {
app_log(LOG_ERROR, "Failed to process admin command");
response_json = cJSON_CreateObject();
cJSON_AddStringToObject(response_json, "status", "error");
cJSON_AddStringToObject(response_json, "message", "Failed to process command");
}
// Convert response to JSON string
char* response_str = cJSON_PrintUnformatted(response_json);
cJSON_Delete(response_json);
if (!response_str) {
app_log(LOG_ERROR, "Failed to serialize response JSON");
return;
}
// Encrypt and send response
char encrypted_response[4096];
if (admin_encrypt_response(server_privkey, admin_pubkey_bytes, response_str,
encrypted_response, sizeof(encrypted_response)) != 0) {
app_log(LOG_ERROR, "Failed to encrypt admin response");
free(response_str);
return;
}
free(response_str);
if (relay_client_send_admin_response(sender_pubkey, encrypted_response) != 0) {
app_log(LOG_ERROR, "Failed to send admin response");
}
}
// Callback for EOSE (End Of Stored Events) - new signature
@@ -661,18 +748,18 @@ static void on_admin_subscription_eose(cJSON** events, int event_count, void* us
app_log(LOG_INFO, "Received EOSE for admin command subscription");
}
// Subscribe to admin commands (Kind 23456)
// Subscribe to admin commands (Kind 23458)
static int subscribe_to_admin_commands(void) {
if (!g_relay_state.pool) {
return -1;
}
app_log(LOG_INFO, "Subscribing to Kind 23456 admin commands...");
app_log(LOG_INFO, "Subscribing to Kind 23458 admin commands...");
// Create subscription filter for Kind 23456 events addressed to us
// Create subscription filter for Kind 23458 events addressed to us
cJSON* filter = cJSON_CreateObject();
cJSON* kinds = cJSON_CreateArray();
cJSON_AddItemToArray(kinds, cJSON_CreateNumber(23456));
cJSON_AddItemToArray(kinds, cJSON_CreateNumber(23458));
cJSON_AddItemToObject(filter, "kinds", kinds);
cJSON* p_tags = cJSON_CreateArray();