First commit on a late git install

This commit is contained in:
2025-08-09 10:23:28 -04:00
commit ca6b4754f9
88 changed files with 18219 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
# NOSTR WebSocket Library Export Guide
This guide explains how to use the NOSTR WebSocket library in other C projects.
## Library Structure
The NOSTR WebSocket library consists of these key files for export:
### Core Files (Required)
- `nostr_websocket_tls.h` - Header with all function declarations and constants
- `nostr_websocket_mbedtls.c` - Main implementation using mbedTLS for SSL/TLS
- `../cjson/cJSON.h` and `../cjson/cJSON.c` - JSON parsing (lightweight)
### Dependencies
- **mbedTLS** - For SSL/TLS support (wss:// connections)
- **Standard C libraries** - socket, networking, etc.
## Quick Integration
### 1. Copy Files to Your Project
```bash
# Copy the library files
cp nostr_websocket_tls.h your_project/
cp nostr_websocket_mbedtls.c your_project/
cp ../cjson/cJSON.h your_project/
cp ../cjson/cJSON.c your_project/
```
### 2. Install mbedTLS Dependency
```bash
# Ubuntu/Debian
sudo apt-get install libmbedtls-dev
# Or build from source (see mbedTLS documentation)
```
### 3. Compile Your Project
```bash
gcc -o my_nostr_app my_app.c nostr_websocket_mbedtls.c cJSON.c \
-lmbedtls -lmbedx509 -lmbedcrypto -lm
```
## Basic Usage Example
```c
#include "nostr_websocket_tls.h"
#include "cJSON.h"
#include <stdio.h>
int main() {
// Connect to relay
nostr_ws_client_t* client = nostr_ws_connect("wss://relay.damus.io");
if (!client) {
printf("Failed to connect\n");
return 1;
}
// Create subscription filter
cJSON* filter = cJSON_CreateObject();
cJSON* kinds = cJSON_CreateArray();
cJSON_AddItemToArray(kinds, cJSON_CreateNumber(1)); // Text notes
cJSON_AddItemToObject(filter, "kinds", kinds);
cJSON_AddItemToObject(filter, "limit", cJSON_CreateNumber(10));
// Send REQ message
nostr_relay_send_req(client, "my-sub", filter);
// Receive messages
char buffer[8192];
while (1) {
int len = nostr_ws_receive(client, buffer, sizeof(buffer), 1000);
if (len > 0) {
printf("Received: %s\n", buffer);
// Parse message type
char* msg_type;
cJSON* parsed;
if (nostr_parse_relay_message(buffer, &msg_type, &parsed) == 0) {
if (strcmp(msg_type, "EOSE") == 0) {
printf("End of subscription\n");
free(msg_type);
cJSON_Delete(parsed);
break;
}
free(msg_type);
cJSON_Delete(parsed);
}
}
}
// Cleanup
nostr_ws_close(client);
cJSON_Delete(filter);
return 0;
}
```
## API Reference
### Connection Management
- `nostr_ws_connect(url)` - Connect to relay (ws:// or wss://)
- `nostr_ws_close(client)` - Close connection and cleanup
- `nostr_ws_get_state(client)` - Get connection state
### Messaging
- `nostr_ws_send_text(client, message)` - Send raw text message
- `nostr_ws_receive(client, buffer, size, timeout)` - Receive message
- `nostr_ws_ping(client)` - Send ping frame
### NOSTR Protocol Helpers
- `nostr_relay_send_req(client, sub_id, filters)` - Send REQ message
- `nostr_relay_send_event(client, event)` - Send EVENT message
- `nostr_relay_send_close(client, sub_id)` - Send CLOSE message
- `nostr_parse_relay_message(message, type, json)` - Parse relay message
### Error Handling
- `nostr_ws_strerror(error_code)` - Get error string
- Return codes: `NOSTR_WS_SUCCESS`, `NOSTR_WS_ERROR_*`
## Advanced Configuration
### Custom Timeouts
```c
nostr_ws_set_timeout(client, 30000); // 30 second timeout
```
### Multiple Transports
The library supports both TCP (`ws://`) and TLS (`wss://`) automatically based on URL scheme.
## Cross-Platform Notes
### Linux/Unix
- Works out of the box with standard development tools
- Requires: gcc, mbedTLS development headers
### Potential Windows Support
- Would need Winsock2 adaptations in transport layer
- mbedTLS is cross-platform compatible
### Embedded Systems
- Lightweight design suitable for embedded use
- Memory usage: ~4KB per client + message buffers
- No dynamic allocations in hot paths
## Library Design Benefits
### Modular Architecture
- Clean separation between WebSocket protocol and NOSTR logic
- Transport layer abstraction (easy to add new transports)
- No global state - multiple clients supported
### Performance Optimized
- Minimal memory allocations
- Efficient SSL buffer handling
- Fast WebSocket frame parsing
### Production Ready
- Proper error handling throughout
- Resource cleanup on all code paths
- Thread-safe design (no shared state)
## Migration from Other Libraries
### From libwebsockets
```c
// Old libwebsockets code:
// lws_client_connect_info info = {...};
// wsi = lws_client_connect(context, &info);
// New NOSTR WebSocket library:
client = nostr_ws_connect("wss://relay.example.com");
```
### From raw sockets
The library handles all WebSocket protocol details, SSL/TLS, and NOSTR message formatting automatically.
## Support
- Based on WebSocket RFC 6455
- Implements NOSTR WebSocket conventions
- SSL/TLS via proven mbedTLS library
- Tested with major NOSTR relays
This library provides a clean, efficient way to integrate NOSTR WebSocket functionality into any C project with minimal dependencies and maximum portability.

63
nostr_websocket/Makefile Normal file
View File

@@ -0,0 +1,63 @@
# NOSTR WebSocket Library Makefile
# Production-ready WebSocket implementation for NOSTR protocol
CC = gcc
CFLAGS = -Wall -Wextra -std=c99 -O2
INCLUDES = -I. -I.. -I../mbedtls/include -I../mbedtls/tf-psa-crypto/include -I../mbedtls/tf-psa-crypto/drivers/builtin/include
LIBS = -lm -L../mbedtls/library -lmbedtls -lmbedx509 -lmbedcrypto
# Source files
WEBSOCKET_SOURCES = nostr_websocket_mbedtls.c ../cjson/cJSON.c
WEBSOCKET_HEADERS = nostr_websocket_tls.h ../cjson/cJSON.h
# Test programs
TEST_SOURCES = test_5_events_clean.c
TEST_PROGRAMS = test_5_events_clean
# Object files
WEBSOCKET_OBJECTS = $(WEBSOCKET_SOURCES:.c=.o)
.PHONY: all clean test
all: $(TEST_PROGRAMS)
# Test programs
test_5_events_clean: test_5_events_clean.o $(WEBSOCKET_OBJECTS)
$(CC) -o $@ $^ $(LIBS)
# Object file compilation
%.o: %.c $(WEBSOCKET_HEADERS)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
# Test target
test: test_5_events_clean
@echo "🧪 Running WebSocket test..."
@echo "Press Ctrl-C to stop the test"
./test_5_events_clean
# Clean build artifacts
clean:
rm -f *.o $(TEST_PROGRAMS)
rm -f ../cjson/*.o
# Display library info
info:
@echo "📚 NOSTR WebSocket Library"
@echo "=========================="
@echo "Core files:"
@echo " - nostr_websocket_tls.h (header)"
@echo " - nostr_websocket_mbedtls.c (implementation)"
@echo " - ../cjson/cJSON.h/c (JSON support)"
@echo ""
@echo "Dependencies:"
@echo " - mbedTLS (SSL/TLS support)"
@echo " - Standard C libraries"
@echo ""
@echo "Usage:"
@echo " make - Build test programs"
@echo " make test - Run WebSocket test"
@echo " make clean - Clean build artifacts"
@echo " make info - Show this information"
# Help target
help: info

139
nostr_websocket/README.md Normal file
View File

@@ -0,0 +1,139 @@
# NOSTR WebSocket Library
A production-ready, lightweight WebSocket client library specifically designed for the NOSTR protocol. This library provides a clean C API for connecting to NOSTR relays over both TCP (`ws://`) and TLS (`wss://`) connections.
## Features
-**WebSocket RFC 6455 Compliant** - Full WebSocket protocol implementation
-**SSL/TLS Support** - Secure `wss://` connections via mbedTLS
-**NOSTR Protocol** - Built-in support for REQ, EVENT, CLOSE messages
-**Production Ready** - Optimized performance and error handling
-**Lightweight** - Minimal dependencies and memory footprint
-**Cross-Platform** - Linux/Unix support, Windows adaptable
-**Thread Safe** - No global state, multiple clients supported
## Quick Start
### 1. Build the Test Program
```bash
make
```
### 2. Run the Test
```bash
make test
# or directly:
./test_5_events_clean
```
### 3. Basic Usage
```c
#include "nostr_websocket_tls.h"
// Connect to a NOSTR relay
nostr_ws_client_t* client = nostr_ws_connect("wss://relay.damus.io");
// Create and send a subscription
cJSON* filter = cJSON_CreateObject();
cJSON_AddItemToObject(filter, "limit", cJSON_CreateNumber(10));
nostr_relay_send_req(client, "my-sub", filter);
// Receive messages
char buffer[8192];
int len = nostr_ws_receive(client, buffer, sizeof(buffer), 1000);
if (len > 0) {
printf("Received: %s\n", buffer);
}
// Cleanup
nostr_ws_close(client);
cJSON_Delete(filter);
```
## Library Structure
### Core Components
- **`nostr_websocket_tls.h`** - Public API header
- **`nostr_websocket_mbedtls.c`** - Main implementation (mbedTLS backend)
- **`../cjson/cJSON.h/c`** - JSON parsing support
### Dependencies
- **mbedTLS** - For SSL/TLS support
- **Standard C libraries** - POSIX sockets, etc.
## Installation in Other Projects
See [`EXPORT_GUIDE.md`](EXPORT_GUIDE.md) for detailed instructions on integrating this library into your C projects.
## API Reference
### Connection Management
```c
nostr_ws_client_t* nostr_ws_connect(const char* url);
int nostr_ws_close(nostr_ws_client_t* client);
nostr_ws_state_t nostr_ws_get_state(nostr_ws_client_t* client);
```
### Messaging
```c
int nostr_ws_send_text(nostr_ws_client_t* client, const char* message);
int nostr_ws_receive(nostr_ws_client_t* client, char* buffer, size_t size, int timeout_ms);
int nostr_ws_ping(nostr_ws_client_t* client);
```
### NOSTR Protocol Helpers
```c
int nostr_relay_send_req(nostr_ws_client_t* client, const char* sub_id, cJSON* filters);
int nostr_relay_send_event(nostr_ws_client_t* client, cJSON* event);
int nostr_relay_send_close(nostr_ws_client_t* client, const char* sub_id);
int nostr_parse_relay_message(const char* message, char** type, cJSON** json);
```
### Error Handling
```c
const char* nostr_ws_strerror(int error_code);
```
## Performance Characteristics
- **Memory Usage**: ~4KB per client + message buffers
- **Latency**: Optimized SSL buffer handling, minimal delays
- **Throughput**: Efficient WebSocket frame parsing
- **Scalability**: Multiple concurrent clients supported
## Tested Relays
This library has been successfully tested with:
- `wss://relay.damus.io`
- `wss://nostr.mom`
- `wss://relay.nostr.band`
- `ws://localhost:7777` (local relays)
## Build Options
```bash
make # Build test programs
make test # Run WebSocket test
make clean # Clean build artifacts
make info # Show library information
make help # Show help
```
## Development History
This library evolved from the experimental WebSocket implementation in `../websocket_experiment/` and represents the production-ready, stable version suitable for integration into other projects.
Key improvements made during development:
- Fixed critical WebSocket frame parsing bugs
- Optimized SSL/TLS performance
- Reduced memory allocations
- Enhanced error handling
- Added comprehensive documentation
## License
This library is part of the C NOSTR project and follows the same license terms.
## Contributing
For issues, improvements, or questions about the NOSTR WebSocket library, please refer to the main project documentation.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
#ifndef NOSTR_WEBSOCKET_TLS_H
#define NOSTR_WEBSOCKET_TLS_H
#include <stddef.h>
#include <stdint.h>
#include "../cjson/cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif
// WebSocket client state
typedef struct nostr_ws_client nostr_ws_client_t;
// Connection states
typedef enum {
NOSTR_WS_CONNECTING = 0,
NOSTR_WS_CONNECTED = 1,
NOSTR_WS_CLOSING = 2,
NOSTR_WS_CLOSED = 3,
NOSTR_WS_ERROR = -1
} nostr_ws_state_t;
// WebSocket opcodes (RFC 6455)
typedef enum {
WS_OPCODE_CONTINUATION = 0x0,
WS_OPCODE_TEXT = 0x1,
WS_OPCODE_BINARY = 0x2,
WS_OPCODE_CLOSE = 0x8,
WS_OPCODE_PING = 0x9,
WS_OPCODE_PONG = 0xA
} ws_opcode_t;
// Error codes
#define NOSTR_WS_SUCCESS 0
#define NOSTR_WS_ERROR_INVALID -1
#define NOSTR_WS_ERROR_NETWORK -2
#define NOSTR_WS_ERROR_PROTOCOL -3
#define NOSTR_WS_ERROR_MEMORY -4
#define NOSTR_WS_ERROR_TLS -5
// Debug control - uncomment to enable debug output
// #define NOSTR_WS_DEBUG_ENABLED
// ============================================================================
// Core WebSocket Functions (with TLS support)
// ============================================================================
/**
* Connect to a WebSocket server (supports both ws:// and wss://)
* @param url WebSocket URL (e.g., "ws://127.0.0.1:7777" or "wss://relay.damus.io")
* @return WebSocket client handle or NULL on error
*/
nostr_ws_client_t* nostr_ws_connect(const char* url);
/**
* Close WebSocket connection
* @param client WebSocket client handle
* @return 0 on success, negative on error
*/
int nostr_ws_close(nostr_ws_client_t* client);
/**
* Get current connection state
* @param client WebSocket client handle
* @return Connection state
*/
nostr_ws_state_t nostr_ws_get_state(nostr_ws_client_t* client);
/**
* Send text message to WebSocket server
* @param client WebSocket client handle
* @param message Text message to send
* @return 0 on success, negative on error
*/
int nostr_ws_send_text(nostr_ws_client_t* client, const char* message);
/**
* Receive message from WebSocket server (blocking)
* @param client WebSocket client handle
* @param buffer Buffer to store received message
* @param buffer_size Size of buffer
* @param timeout_ms Timeout in milliseconds (0 = no timeout)
* @return Number of bytes received, negative on error
*/
int nostr_ws_receive(nostr_ws_client_t* client, char* buffer, size_t buffer_size, int timeout_ms);
/**
* Send ping frame to server
* @param client WebSocket client handle
* @return 0 on success, negative on error
*/
int nostr_ws_ping(nostr_ws_client_t* client);
// ============================================================================
// NOSTR-Specific Helper Functions
// ============================================================================
/**
* Send NOSTR REQ message to relay
* @param client WebSocket client handle
* @param subscription_id Subscription ID
* @param filters JSON array of filters
* @return 0 on success, negative on error
*/
int nostr_relay_send_req(nostr_ws_client_t* client, const char* subscription_id, cJSON* filters);
/**
* Send NOSTR EVENT message to relay
* @param client WebSocket client handle
* @param event NOSTR event JSON object
* @return 0 on success, negative on error
*/
int nostr_relay_send_event(nostr_ws_client_t* client, cJSON* event);
/**
* Send NOSTR CLOSE message to relay
* @param client WebSocket client handle
* @param subscription_id Subscription ID to close
* @return 0 on success, negative on error
*/
int nostr_relay_send_close(nostr_ws_client_t* client, const char* subscription_id);
/**
* Parse received NOSTR message
* @param message Raw message string
* @param message_type Output: message type ("EVENT", "EOSE", "OK", "NOTICE")
* @param parsed_json Output: parsed JSON object (caller must free)
* @return 0 on success, negative on error
*/
int nostr_parse_relay_message(const char* message, char** message_type, cJSON** parsed_json);
// ============================================================================
// Utility Functions
// ============================================================================
/**
* Get error string for error code
* @param error_code Error code from WebSocket functions
* @return Human-readable error string
*/
const char* nostr_ws_strerror(int error_code);
/**
* Set receive timeout for blocking operations
* @param client WebSocket client handle
* @param timeout_ms Timeout in milliseconds
* @return 0 on success, negative on error
*/
int nostr_ws_set_timeout(nostr_ws_client_t* client, int timeout_ms);
#ifdef __cplusplus
}
#endif
#endif // NOSTR_WEBSOCKET_TLS_H