# Exportable C NOSTR Library Design Guide This document outlines the design principles and structure for making the C NOSTR library easily exportable and reusable across multiple projects. ## Overview The C NOSTR library is designed as a modular, self-contained implementation that can be easily integrated into other projects while maintaining compatibility with the broader NOSTR ecosystem. ## Design Principles ### 1. Modular Architecture - **Core Layer**: Essential NOSTR functionality (`nostr_core.c/h`) - **Crypto Layer**: Self-contained cryptographic primitives (`nostr_crypto.c/h`) - **WebSocket Layer**: Optional networking functionality (`nostr_websocket/`) - **Dependencies**: Minimal external dependencies (only cJSON and mbedTLS) ### 2. Clean API Surface - Consistent function naming with `nostr_` prefix - Clear return codes using `NOSTR_SUCCESS`/`NOSTR_ERROR_*` constants - Well-documented function signatures - No global state where possible ### 3. Self-Contained Crypto - Custom implementations of SHA-256, HMAC, secp256k1 - BIP39 wordlist embedded in code - No external crypto library dependencies for core functionality - Optional mbedTLS integration for enhanced security ### 4. Cross-Platform Compatibility - Standard C99 code - Platform-specific code isolated in separate modules - ARM64 and x86_64 tested builds - Static library compilation support ## Library Structure ``` c_nostr/ ├── nostr_core.h # High-level API ├── nostr_core.c # Implementation ├── nostr_crypto.h # Crypto primitives API ├── nostr_crypto.c # Self-contained crypto ├── libnostr_core.a # Static library (x86_64) ├── libnostr_core.so # Shared library (x86_64) ├── cjson/ # JSON parsing (vendored) ├── mbedtls/ # Optional crypto backend ├── examples/ # Usage examples ├── tests/ # Test suites └── nostr_websocket/ # Optional WebSocket layer ``` ## Integration Methods ### Method 1: Static Library Linking **Best for**: Applications that want a single binary with all NOSTR functionality embedded. ```bash # Build the library make lib # In your project Makefile: CFLAGS += -I/path/to/c_nostr LDFLAGS += -L/path/to/c_nostr -lnostr_core -lm -static ``` **Usage:** ```c #include "nostr_core.h" int main() { if (nostr_init() != NOSTR_SUCCESS) { return 1; } unsigned char private_key[32], public_key[32]; nostr_generate_keypair(private_key, public_key); cJSON* event = nostr_create_text_event("Hello NOSTR!", private_key); // ... use event nostr_cleanup(); return 0; } ``` ### Method 2: Source Code Integration **Best for**: Applications that want to customize the crypto backend or minimize dependencies. ```bash # Copy essential files to your project: cp nostr_core.{c,h} your_project/src/ cp nostr_crypto.{c,h} your_project/src/ cp -r cjson/ your_project/src/ ``` **Compile with your project:** ```c // In your source #include "nostr_core.h" // Use NOSTR functions directly ``` ### Method 3: Git Submodule **Best for**: Projects that want to track upstream changes and contribute back. ```bash # In your project root: git submodule add https://github.com/yourorg/c_nostr.git deps/c_nostr git submodule update --init --recursive # In your Makefile: CFLAGS += -Ideps/c_nostr LDFLAGS += -Ldeps/c_nostr -lnostr_core ``` ### Method 4: Shared Library **Best for**: System-wide installation or multiple applications sharing the same NOSTR implementation. ```bash # Install system-wide sudo make install # In your project: CFLAGS += $(pkg-config --cflags nostr_core) LDFLAGS += $(pkg-config --libs nostr_core) ``` ## API Design for Exportability ### Consistent Error Handling ```c typedef enum { NOSTR_SUCCESS = 0, NOSTR_ERROR_INVALID_INPUT = -1, NOSTR_ERROR_CRYPTO_FAILED = -2, NOSTR_ERROR_MEMORY_ALLOCATION = -3, NOSTR_ERROR_JSON_PARSE = -4, NOSTR_ERROR_NETWORK = -5 } nostr_error_t; const char* nostr_strerror(int error_code); ``` ### Clean Resource Management ```c // Always provide cleanup functions int nostr_init(void); void nostr_cleanup(void); // JSON objects returned should be freed by caller cJSON* nostr_create_text_event(const char* content, const unsigned char* private_key); // Caller must call cJSON_Delete(event) when done ``` ### Optional Features ```c // Compile-time feature toggles #ifndef NOSTR_DISABLE_WEBSOCKETS int nostr_connect_relay(const char* url); #endif #ifndef NOSTR_DISABLE_IDENTITY_PERSISTENCE int nostr_save_identity(const unsigned char* private_key, const char* password, int account); #endif ``` ## Configuration System ### Build-Time Configuration ```c // nostr_config.h (generated during build) #define NOSTR_VERSION "1.0.0" #define NOSTR_HAS_MBEDTLS 1 #define NOSTR_HAS_WEBSOCKETS 1 #define NOSTR_STATIC_BUILD 1 ``` ### Runtime Configuration ```c typedef struct { int log_level; char* identity_file_path; int default_account; int enable_networking; } nostr_config_t; int nostr_set_config(const nostr_config_t* config); const nostr_config_t* nostr_get_config(void); ``` ## Testing and Validation ### Ecosystem Compatibility Testing The library includes comprehensive test suites that validate compatibility with reference implementations like `nak`: ```bash # Run all tests cd tests && make test # Test specific functionality make test-crypto # Cryptographic primitives make test-core # High-level NOSTR functions ``` ### Test Vectors Real-world test vectors are generated using `nak` to ensure ecosystem compatibility: - Key generation and derivation (BIP39/BIP32) - Event creation and signing - Bech32 encoding/decoding - Message serialization ## Documentation for Exporters ### Essential Files Checklist For projects integrating this library, you need: **Core Files (Required):** - `nostr_core.h` - Main API - `nostr_core.c` - Implementation - `nostr_crypto.h` - Crypto API - `nostr_crypto.c` - Self-contained crypto - `cjson/` directory - JSON parsing **Optional Files:** - `nostr_websocket/` - WebSocket relay support - `mbedtls/` - Enhanced crypto backend - `examples/` - Usage examples - `tests/` - Validation tests ### Minimal Integration Example ```c // minimal_nostr.c - Smallest possible integration #include "nostr_core.h" int main() { // Initialize library nostr_init(); // Generate keypair unsigned char priv[32], pub[32]; nostr_generate_keypair(priv, pub); // Create and sign event cJSON* event = nostr_create_text_event("Hello from my app!", priv); char* json_string = cJSON_Print(event); printf("Event: %s\n", json_string); // Cleanup free(json_string); cJSON_Delete(event); nostr_cleanup(); return 0; } ``` **Compile:** ```bash gcc -I. minimal_nostr.c nostr_core.c nostr_crypto.c cjson/cJSON.c -lm -o minimal_nostr ``` ## Future Considerations ### Language Bindings The C library is designed to be easily wrapped: - **Python**: Use ctypes or cffi - **JavaScript**: Use Node.js FFI or WASM compilation - **Go**: Use cgo - **Rust**: Use bindgen for FFI bindings ### WebAssembly Support The library can be compiled to WebAssembly for browser usage: ```bash emcc -O3 -s WASM=1 -s EXPORTED_FUNCTIONS='["_nostr_init", "_nostr_generate_keypair"]' \ nostr_core.c nostr_crypto.c cjson/cJSON.c -o nostr.wasm ``` ### Package Manager Support Future versions may include: - pkgconfig files for system installation - CMake integration for easier builds - vcpkg/Conan package definitions ## Contributing Back Projects using this library are encouraged to: 1. Report compatibility issues 2. Submit test vectors from their use cases 3. Contribute performance improvements 4. Add support for additional NIPs ## Version Compatibility The library follows semantic versioning: - **Major**: Breaking API changes - **Minor**: New features, backward compatible - **Patch**: Bug fixes API stability guarantees: - All functions prefixed with `nostr_` are part of the stable API - Internal functions (static or prefixed with `_`) may change - Configuration structures may be extended but not modified --- This design ensures the C NOSTR library can be easily adopted by other projects while maintaining high compatibility with the NOSTR ecosystem standards.