v0.0.2 - Got it basically working

This commit is contained in:
Your Name
2025-12-10 13:30:32 -04:00
parent 60543cf7c4
commit c76f10491a
3 changed files with 564 additions and 5 deletions

186
main.c
View File

@@ -29,7 +29,7 @@
#include "cJSON.h"
// Version
#define THROWER_VERSION "v0.0.1"
#define THROWER_VERSION "v0.0.2"
// Configuration constants
#define MAX_RELAYS 50
@@ -177,6 +177,8 @@ static void free_padding_payload(padding_payload_t* payload);
// Thrower info functions
static int publish_thrower_info(superball_thrower_t* thrower);
static int publish_metadata(superball_thrower_t* thrower);
static int publish_relay_list(superball_thrower_t* thrower);
static void* auto_publish_thread_func(void* arg);
// Main functions
@@ -793,6 +795,13 @@ static void forward_to_next_thrower(superball_thrower_t* thrower, cJSON* event,
return;
}
// Log the event JSON being published
char* event_json = cJSON_Print(signed_event);
if (event_json) {
log_message(LOG_INFO, "Publishing routing event JSON:\n%s", event_json);
free(event_json);
}
// Publish to relays
nostr_relay_pool_publish_async(thrower->pool, (const char**)routing->relays,
routing->relay_count, signed_event,
@@ -803,14 +812,29 @@ static void forward_to_next_thrower(superball_thrower_t* thrower, cJSON* event,
}
static void post_final_event(superball_thrower_t* thrower, cJSON* event, routing_payload_t* routing) {
(void)event; // The wrapped event is not used - we publish the inner event from routing
log_message(LOG_INFO, "Posting final event to %d relays", routing->relay_count);
// Publish the inner event directly
// The inner event is in routing->event (this is the kind 1 note, not the kind 22222 wrapper)
if (!routing->event) {
log_message(LOG_ERROR, "No inner event to publish");
return;
}
// Log the inner event JSON being published
char* event_json = cJSON_Print(routing->event);
if (event_json) {
log_message(LOG_INFO, "Publishing final event JSON:\n%s", event_json);
free(event_json);
}
// Publish the inner event directly (this is the actual kind 1 note)
nostr_relay_pool_publish_async(thrower->pool, (const char**)routing->relays,
routing->relay_count, event,
routing->relay_count, routing->event,
publish_callback, thrower);
cJSON* id = cJSON_GetObjectItem(event, "id");
cJSON* id = cJSON_GetObjectItem(routing->event, "id");
if (id) {
log_message(LOG_INFO, "Final event posted: %.16s...", cJSON_GetStringValue(id));
}
@@ -818,12 +842,23 @@ static void post_final_event(superball_thrower_t* thrower, cJSON* event, routing
static void publish_callback(const char* relay_url, const char* event_id, int success,
const char* message, void* user_data) {
(void)user_data; // Suppress unused parameter warning
superball_thrower_t* thrower = (superball_thrower_t*)user_data;
if (success) {
log_message(LOG_INFO, "✅ Published to %s: %.16s...", relay_url, event_id);
// Print relay response if available
if (message) {
log_message(LOG_DEBUG, "Relay response: %s", message);
}
} else {
log_message(LOG_ERROR, "❌ Failed to publish to %s: %s", relay_url, message ? message : "unknown error");
}
// Note: We don't have access to the full event JSON here in the callback
// The event was already published. To see the full event, we'd need to
// log it before calling nostr_relay_pool_publish_async
(void)thrower; // Suppress unused warning for now
}
static void free_routing_payload(routing_payload_t* payload) {
@@ -940,6 +975,143 @@ static int publish_thrower_info(superball_thrower_t* thrower) {
return 0;
}
static int publish_metadata(superball_thrower_t* thrower) {
log_message(LOG_INFO, "Publishing metadata (kind 0)...");
// Create metadata JSON content
cJSON* metadata = cJSON_CreateObject();
if (thrower->config->name) {
cJSON_AddStringToObject(metadata, "name", thrower->config->name);
}
if (thrower->config->description) {
cJSON_AddStringToObject(metadata, "about", thrower->config->description);
}
// Add Superball-specific fields
if (thrower->config->software) {
cJSON_AddStringToObject(metadata, "nip05", thrower->config->software);
}
// Add version and supported SUPs
if (thrower->config->version) {
cJSON_AddStringToObject(metadata, "display_name",
thrower->config->version);
}
if (thrower->config->supported_sups) {
cJSON_AddStringToObject(metadata, "website",
thrower->config->supported_sups);
}
char* content = cJSON_PrintUnformatted(metadata);
cJSON_Delete(metadata);
if (!content) {
log_message(LOG_ERROR, "Failed to create metadata JSON");
return -1;
}
// Create kind 0 event with empty tags
cJSON* tags = cJSON_CreateArray();
cJSON* event = nostr_create_and_sign_event(0, content, tags,
thrower->private_key, time(NULL));
free(content);
cJSON_Delete(tags);
if (!event) {
log_message(LOG_ERROR, "Failed to create metadata event");
return -1;
}
// Get write-capable relays
const char** relay_urls = malloc(thrower->config->relay_count * sizeof(char*));
int relay_count = 0;
for (int i = 0; i < thrower->config->relay_count; i++) {
if (thrower->config->relays[i].write &&
strcmp(thrower->config->relays[i].auth_status, "no-auth") == 0) {
relay_urls[relay_count++] = thrower->config->relays[i].url;
}
}
if (relay_count == 0) {
log_message(LOG_WARN, "No write-capable relays for metadata");
free(relay_urls);
cJSON_Delete(event);
return -1;
}
nostr_relay_pool_publish_async(thrower->pool, relay_urls, relay_count,
event, publish_callback, thrower);
free(relay_urls);
cJSON_Delete(event);
log_message(LOG_INFO, "Metadata published to %d relays", relay_count);
return 0;
}
static int publish_relay_list(superball_thrower_t* thrower) {
log_message(LOG_INFO, "Publishing relay list (kind 10002)...");
// Create tags array with relay information
cJSON* tags = cJSON_CreateArray();
for (int i = 0; i < thrower->config->relay_count; i++) {
cJSON* relay_tag = cJSON_CreateArray();
cJSON_AddItemToArray(relay_tag, cJSON_CreateString("r"));
cJSON_AddItemToArray(relay_tag, cJSON_CreateString(thrower->config->relays[i].url));
// Add read/write markers
if (thrower->config->relays[i].read && thrower->config->relays[i].write) {
// Both read and write - no marker needed (default)
} else if (thrower->config->relays[i].read) {
cJSON_AddItemToArray(relay_tag, cJSON_CreateString("read"));
} else if (thrower->config->relays[i].write) {
cJSON_AddItemToArray(relay_tag, cJSON_CreateString("write"));
}
cJSON_AddItemToArray(tags, relay_tag);
}
// Create kind 10002 event with empty content
cJSON* event = nostr_create_and_sign_event(10002, "", tags,
thrower->private_key, time(NULL));
cJSON_Delete(tags);
if (!event) {
log_message(LOG_ERROR, "Failed to create relay list event");
return -1;
}
// Get write-capable relays
const char** relay_urls = malloc(thrower->config->relay_count * sizeof(char*));
int relay_count = 0;
for (int i = 0; i < thrower->config->relay_count; i++) {
if (thrower->config->relays[i].write &&
strcmp(thrower->config->relays[i].auth_status, "no-auth") == 0) {
relay_urls[relay_count++] = thrower->config->relays[i].url;
}
}
if (relay_count == 0) {
log_message(LOG_WARN, "No write-capable relays for relay list");
free(relay_urls);
cJSON_Delete(event);
return -1;
}
nostr_relay_pool_publish_async(thrower->pool, relay_urls, relay_count,
event, publish_callback, thrower);
free(relay_urls);
cJSON_Delete(event);
log_message(LOG_INFO, "Relay list published to %d relays", relay_count);
return 0;
}
static void* auto_publish_thread_func(void* arg) {
superball_thrower_t* thrower = (superball_thrower_t*)arg;
@@ -1078,6 +1250,10 @@ static int thrower_start(superball_thrower_t* thrower) {
log_message(LOG_INFO, "Monitoring %d relays for routing events", thrower->config->relay_count);
// Publish initial metadata and relay list
publish_metadata(thrower);
publish_relay_list(thrower);
// Publish initial thrower info
publish_thrower_info(thrower);