# NOSTR Core Library A C library for NOSTR protocol implementation. Work in progress. [![Version](https://img.shields.io/badge/version-0.2.1-blue.svg)](VERSION) [![License](https://img.shields.io/badge/license-MIT-green.svg)](#license) [![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg)](#building) ## ๐Ÿ“‹ NIP Implementation Status ### Core Protocol NIPs - [x] [NIP-01](nips/01.md) - Basic protocol flow - event creation, signing, and validation - [ ] [NIP-02](nips/02.md) - Contact List and Petnames - [ ] [NIP-03](nips/03.md) - OpenTimestamps Attestations for Events - [x] [NIP-04](nips/04.md) - Encrypted Direct Messages (legacy) - [x] [NIP-05](nips/05.md) - Mapping Nostr keys to DNS-based internet identifiers - [x] [NIP-06](nips/06.md) - Basic key derivation from mnemonic seed phrase - [ ] [NIP-07](nips/07.md) - `window.nostr` capability for web browsers - [ ] [NIP-08](nips/08.md) - Handling Mentions - [ ] [NIP-09](nips/09.md) - Event Deletion - [ ] [NIP-10](nips/10.md) - Conventions for clients' use of `e` and `p` tags in text events - [x] [NIP-11](nips/11.md) - Relay Information Document - [ ] [NIP-12](nips/12.md) - Generic Tag Queries - [x] [NIP-13](nips/13.md) - Proof of Work - [ ] [NIP-14](nips/14.md) - Subject tag in text events - [ ] [NIP-15](nips/15.md) - Nostr Marketplace (for resilient marketplaces) - [ ] [NIP-16](nips/16.md) - Event Treatment - [x] [NIP-17](nips/17.md) - Private Direct Messages - [ ] [NIP-18](nips/18.md) - Reposts - [x] [NIP-19](nips/19.md) - bech32-encoded entities - [ ] [NIP-20](nips/20.md) - Command Results - [x] [NIP-21](nips/21.md) - `nostr:` URI scheme - [ ] [NIP-22](nips/22.md) - Event `created_at` Limits - [ ] [NIP-23](nips/23.md) - Long-form Content - [ ] [NIP-24](nips/24.md) - Extra metadata fields and tags - [ ] [NIP-25](nips/25.md) - Reactions - [ ] [NIP-26](nips/26.md) - Delegated Event Signing - [ ] [NIP-27](nips/27.md) - Text Note References - [ ] [NIP-28](nips/28.md) - Public Chat - [ ] [NIP-29](nips/29.md) - Relay-based Groups - [ ] [NIP-30](nips/30.md) - Custom Emoji - [ ] [NIP-31](nips/31.md) - Dealing with Unknown Events - [ ] [NIP-32](nips/32.md) - Labeling - [ ] [NIP-33](nips/33.md) - Parameterized Replaceable Events - [ ] [NIP-34](nips/34.md) - `git` stuff - [ ] [NIP-35](nips/35.md) - Torrents - [ ] [NIP-36](nips/36.md) - Sensitive Content / Content Warning - [ ] [NIP-37](nips/37.md) - Draft Events - [ ] [NIP-38](nips/38.md) - User Statuses - [ ] [NIP-39](nips/39.md) - External Identities in Profiles - [ ] [NIP-40](nips/40.md) - Expiration Timestamp - [x] [NIP-42](nips/42.md) - Authentication of clients to relays - [x] [NIP-44](nips/44.md) - Versioned Encryption - [ ] [NIP-45](nips/45.md) - Counting results - [ ] [NIP-46](nips/46.md) - Nostr Connect - [ ] [NIP-47](nips/47.md) - Wallet Connect - [ ] [NIP-48](nips/48.md) - Proxy Tags - [ ] [NIP-49](nips/49.md) - Private Key Encryption - [ ] [NIP-50](nips/50.md) - Search Capability - [ ] [NIP-51](nips/51.md) - Lists - [ ] [NIP-52](nips/52.md) - Calendar Events - [ ] [NIP-53](nips/53.md) - Live Activities - [ ] [NIP-54](nips/54.md) - Wiki - [ ] [NIP-55](nips/55.md) - Android Signer Application - [ ] [NIP-56](nips/56.md) - Reporting - [ ] [NIP-57](nips/57.md) - Lightning Zaps - [ ] [NIP-58](nips/58.md) - Badges - [x] [NIP-59](nips/59.md) - Gift Wrap - [ ] [NIP-60](nips/60.md) - Cashu Wallet - [ ] [NIP-61](nips/61.md) - Nutzaps - [ ] [NIP-62](nips/62.md) - Log events - [ ] [NIP-64](nips/64.md) - Chess (PGN) - [ ] [NIP-65](nips/65.md) - Relay List Metadata - [ ] [NIP-66](nips/66.md) - Relay Monitor - [ ] [NIP-68](nips/68.md) - Web badges - [ ] [NIP-69](nips/69.md) - Peer-to-peer Order events - [ ] [NIP-70](nips/70.md) - Protected Events - [ ] [NIP-71](nips/71.md) - Video Events - [ ] [NIP-72](nips/72.md) - Moderated Communities - [ ] [NIP-73](nips/73.md) - External Content IDs - [ ] [NIP-75](nips/75.md) - Zap Goals - [ ] [NIP-77](nips/77.md) - Arbitrary custom app data - [ ] [NIP-78](nips/78.md) - Application-specific data - [ ] [NIP-84](nips/84.md) - Highlights - [ ] [NIP-86](nips/86.md) - Relay Management API - [ ] [NIP-87](nips/87.md) - Relay List Recommendations - [ ] [NIP-88](nips/88.md) - Stella: A Stellar Relay - [ ] [NIP-89](nips/89.md) - Recommended Application Handlers - [ ] [NIP-90](nips/90.md) - Data Vending Machines - [ ] [NIP-92](nips/92.md) - Media Attachments - [ ] [NIP-94](nips/94.md) - File Metadata - [ ] [NIP-96](nips/96.md) - HTTP File Storage Integration - [ ] [NIP-98](nips/98.md) - HTTP Auth - [ ] [NIP-99](nips/99.md) - Classified Listings **Legend:** โœ… Fully Implemented | โš ๏ธ Partial Implementation | โŒ Not Implemented **Implementation Summary:** 12 of 96+ NIPs fully implemented (12.5%) ## ๐Ÿ“ฆ Quick Start ### Installation 1. **Clone the repository:** ```bash git clone https://github.com/yourusername/nostr_core_lib.git cd nostr_core_lib ``` 2. **Build the library:** ```bash ./build.sh lib ``` 3. **Run examples:** ```bash ./build.sh examples ./examples/simple_keygen ``` ### Usage Example ```c #include "nostr_core/nostr_core.h" #include int main() { // Initialize library if (nostr_init() != NOSTR_SUCCESS) { fprintf(stderr, "Failed to initialize NOSTR library\n"); return 1; } // Generate keypair unsigned char private_key[32], public_key[32]; nostr_generate_keypair(private_key, public_key); // Convert to bech32 format char nsec[100], npub[100]; nostr_key_to_bech32(private_key, "nsec", nsec); nostr_key_to_bech32(public_key, "npub", npub); printf("Private key: %s\n", nsec); printf("Public key: %s\n", npub); // Create and sign event cJSON* event = nostr_create_and_sign_event(1, "Hello NOSTR!", NULL, private_key, 0); if (event) { char* json = cJSON_Print(event); printf("Event: %s\n", json); free(json); cJSON_Delete(event); } nostr_cleanup(); return 0; } ``` **Compile and run:** ```bash gcc example.c -o example ./libnostr_core.a -lm ./example ``` ## ๐Ÿ—๏ธ Building ### Build Targets ```bash ./build.sh lib # Build static library (default) ./build.sh examples # Build examples ./build.sh test # Run test suite ./build.sh clean # Clean build artifacts ./build.sh install # Install to system ``` ### Manual Building ```bash # Build static library make # Build examples make examples # Run tests make test-crypto # Clean make clean ``` ### Dependencies **Required System Dependencies:** - GCC or compatible C compiler - Standard C library and math library (`-lm`) - OpenSSL development libraries (`-lssl -lcrypto`) - curl development libraries (`-lcurl`) - secp256k1 development libraries (`-lsecp256k1`) **Install on Ubuntu/Debian:** ```bash sudo apt install build-essential libssl-dev libcurl4-openssl-dev libsecp256k1-dev ``` **Install on CentOS/RHEL:** ```bash sudo yum install gcc openssl-devel libcurl-devel libsecp256k1-devel ``` **Install on macOS:** ```bash brew install openssl curl secp256k1 ``` **Still Bundled:** - cJSON (JSON parsing - internal copy) - TinyAES-c (AES encryption for NIP-04) - ChaCha20 (stream cipher for NIP-44) ## ๐Ÿ“š API Documentation ### Initialization ```c int nostr_init(void); // Initialize library (call first) void nostr_cleanup(void); // Cleanup resources (call last) const char* nostr_strerror(int error); // Get error message ``` ### Key Management ```c // Generate random keypair int nostr_generate_keypair(unsigned char* private_key, unsigned char* public_key); // Generate from mnemonic int nostr_generate_mnemonic_and_keys(char* mnemonic, size_t mnemonic_size, int account, unsigned char* private_key, unsigned char* public_key); // Derive from existing mnemonic int nostr_derive_keys_from_mnemonic(const char* mnemonic, int account, unsigned char* private_key, unsigned char* public_key); // Format conversion int nostr_key_to_bech32(const unsigned char* key, const char* hrp, char* output); nostr_input_type_t nostr_detect_input_type(const char* input); ``` ### Event Creation ```c // Create and sign event cJSON* nostr_create_and_sign_event(int kind, const char* content, cJSON* tags, const unsigned char* private_key, time_t timestamp); // Add proof of work int nostr_add_proof_of_work(cJSON* event, const unsigned char* private_key, int target_difficulty, void (*progress_callback)(...), void* user_data); ``` ### Encryption (NIP-04 & NIP-44) ```c // NIP-04 (AES-CBC) int nostr_nip04_encrypt(const unsigned char* sender_private_key, const unsigned char* recipient_public_key, const char* plaintext, char* output, size_t output_size); int nostr_nip04_decrypt(const unsigned char* recipient_private_key, const unsigned char* sender_public_key, const char* encrypted_data, char* output, size_t output_size); // NIP-44 (ChaCha20) int nostr_nip44_encrypt(const unsigned char* sender_private_key, const unsigned char* recipient_public_key, const char* plaintext, char* output, size_t output_size); int nostr_nip44_decrypt(const unsigned char* recipient_private_key, const unsigned char* sender_public_key, const char* encrypted_data, char* output, size_t output_size); ``` ### Relay Communication ```c // Simple relay query cJSON* nostr_query_relay_for_event(const char* relay_url, const char* pubkey_hex, int kind); // Multi-relay synchronous queries cJSON** synchronous_query_relays_with_progress(const char** relay_urls, int relay_count, cJSON* filter, relay_query_mode_t mode, int* result_count, int relay_timeout_seconds, relay_progress_callback_t callback, void* user_data); // Multi-relay publishing publish_result_t* synchronous_publish_event_with_progress(const char** relay_urls, int relay_count, cJSON* event, int* success_count, int relay_timeout_seconds, publish_progress_callback_t callback, void* user_data); ``` ### Relay Pools (Asynchronous) ```c // Create and manage relay pool with reconnection nostr_pool_reconnect_config_t* config = nostr_pool_reconnect_config_default(); nostr_relay_pool_t* nostr_relay_pool_create(nostr_pool_reconnect_config_t* config); int nostr_relay_pool_add_relay(nostr_relay_pool_t* pool, const char* relay_url); void nostr_relay_pool_destroy(nostr_relay_pool_t* pool); // Subscribe to events (with auto-reconnection) nostr_pool_subscription_t* nostr_relay_pool_subscribe( nostr_relay_pool_t* pool, const char** relay_urls, int relay_count, cJSON* filter, void (*on_event)(cJSON* event, const char* relay_url, void* user_data), void (*on_eose)(void* user_data), void* user_data, int close_on_eose); // Run event loop (handles reconnection automatically) int nostr_relay_pool_run(nostr_relay_pool_t* pool, int timeout_ms); int nostr_relay_pool_poll(nostr_relay_pool_t* pool, int timeout_ms); // Reconnection configuration typedef struct { int enable_auto_reconnect; // Enable automatic reconnection int max_reconnect_attempts; // Maximum retry attempts int initial_reconnect_delay_ms; // Initial delay between attempts int max_reconnect_delay_ms; // Maximum delay cap int reconnect_backoff_multiplier; // Exponential backoff factor int ping_interval_seconds; // Health check ping interval int pong_timeout_seconds; // Pong response timeout } nostr_pool_reconnect_config_t; ``` ### NIP-05 Identifier Verification ```c // Lookup public key from NIP-05 identifier int nostr_nip05_lookup(const char* nip05_identifier, char* pubkey_hex_out, char*** relays, int* relay_count, int timeout_seconds); // Verify NIP-05 identifier against public key int nostr_nip05_verify(const char* nip05_identifier, const char* pubkey_hex, char*** relays, int* relay_count, int timeout_seconds); // Parse .well-known/nostr.json response int nostr_nip05_parse_well_known(const char* json_response, const char* local_part, char* pubkey_hex_out, char*** relays, int* relay_count); ``` ### NIP-11 Relay Information ```c // Fetch relay information document int nostr_nip11_fetch_relay_info(const char* relay_url, nostr_relay_info_t** info_out, int timeout_seconds); // Free relay information structure void nostr_nip11_relay_info_free(nostr_relay_info_t* info); ``` ## ๐Ÿ“ Examples The library includes comprehensive examples: - **`simple_keygen`** - Basic key generation and formatting - **`keypair_generation`** - Advanced key management - **`mnemonic_generation`** - BIP39 mnemonic handling - **`mnemonic_derivation`** - NIP-06 key derivation - **`utility_functions`** - General utility demonstrations - **`input_detection`** - Input type detection and processing - **`version_test`** - Library version information Run all examples: ```bash ./build.sh examples ls -la examples/ ``` ## ๐Ÿงช Testing The library includes extensive tests: ```bash # Run all tests ./build.sh test # Individual test categories cd tests && make test # Interactive relay pool testing cd tests && ./pool_test ``` **Test Categories:** - **Core Functionality**: `simple_init_test`, `header_test` - **Cryptography**: `chacha20_test`, `nostr_crypto_test` - **NIP-04 Encryption**: `nip04_test` - **NIP-05 Identifiers**: `nip05_test` - **NIP-11 Relay Info**: `nip11_test` - **NIP-44 Encryption**: `nip44_test`, `nip44_debug_test` - **Key Derivation**: `nostr_test_bip32` - **Relay Communication**: `relay_pool_test`, `sync_test` - **HTTP/WebSocket**: `http_test`, `wss_test` - **Proof of Work**: `test_pow_loop` - **Interactive Pool Testing**: `pool_test` (menu-driven interface with reconnection testing) ## ๐Ÿ—๏ธ Integration ### Static Library Integration (Recommended) 1. **Install system dependencies first** (see Dependencies section above) 2. **Copy required files to your project:** ```bash cp libnostr_core.a /path/to/your/project/ cp nostr_core/nostr_core.h /path/to/your/project/ ``` 3. **Link in your project:** ```bash gcc your_code.c -L. -lnostr_core -lssl -lcrypto -lcurl -lsecp256k1 -lm -o your_program ``` ### Source Integration 1. **Install system dependencies first** (see Dependencies section above) 2. **Copy source files:** ```bash cp -r nostr_core/ /path/to/your/project/ cp -r cjson/ /path/to/your/project/ ``` 3. **Include in your build:** ```bash gcc your_code.c nostr_core/*.c cjson/cJSON.c -lssl -lcrypto -lcurl -lsecp256k1 -lm -o your_program ``` ### System Dependencies Library The `libnostr_core.a` library now uses **system dependencies** for all major crypto libraries: - โœ… **Uses system OpenSSL** (`-lssl -lcrypto`) - โœ… **Uses system curl** (`-lcurl`) - โœ… **Uses system secp256k1** (`-lsecp256k1`) - โœ… **Includes only internal code** (cJSON, TinyAES, ChaCha20) **Complete linking example:** ```bash gcc your_app.c ./libnostr_core.a -lssl -lcrypto -lcurl -lsecp256k1 -lm -o your_app ``` **Check system dependencies:** ```bash ldd your_app # Shows linked system libraries ``` ## ๐Ÿ”ง Configuration ### Compile-Time Options ```c // Enable debug output #define NOSTR_DEBUG_ENABLED // Crypto-only build (no networking) #define NOSTR_CRYPTO_ONLY // Enable specific NIPs #define NOSTR_NIP04_ENABLED #define NOSTR_NIP44_ENABLED #define NOSTR_NIP13_ENABLED ``` ### Build Flags ```bash # Enable all logging make LOGGING_FLAGS="-DENABLE_FILE_LOGGING -DENABLE_WEBSOCKET_LOGGING -DENABLE_DEBUG_LOGGING" # Debug build make debug # ARM64 cross-compile make arm64 ``` ## ๐ŸŒ Supported Platforms - **Linux** (x86_64, ARM64) - **macOS** (Intel, Apple Silicon) - **Windows** (MinGW, MSYS2) - **Embedded Systems** (resource-constrained environments) ## ๐Ÿ“„ Documentation - **[LIBRARY_USAGE.md](LIBRARY_USAGE.md)** - Detailed integration guide - **[EXPORT_GUIDE.md](EXPORT_GUIDE.md)** - Library export instructions - **[AUTOMATIC_VERSIONING.md](AUTOMATIC_VERSIONING.md)** - Version management - **API Reference** - Complete documentation in `nostr_core/nostr_core.h` ## ๐Ÿค Contributing 1. Fork the repository 2. Create a feature branch: `git checkout -b feature/amazing-feature` 3. Make your changes and add tests 4. Run the test suite: `./build.sh test` 5. Commit your changes: `git commit -m 'Add amazing feature'` 6. Push to the branch: `git push origin feature/amazing-feature` 7. Open a Pull Request ## ๐Ÿ“ˆ Version History Current version: **0.2.1** The library uses automatic semantic versioning based on Git tags. Each build increments the patch version automatically. **Recent Developments:** - **OpenSSL Migration**: Transitioned from mbedTLS to OpenSSL for improved compatibility - **NIP-05 Support**: DNS-based internet identifier verification - **NIP-11 Support**: Relay information document fetching and parsing - **NIP-19 Support**: Bech32-encoded entities (nsec/npub) - **Enhanced WebSocket**: OpenSSL-based TLS WebSocket communication - **Comprehensive Testing**: Extensive test suite and error handling **Version Timeline:** - `v0.2.x` - Current development releases with enhanced NIP support - `v0.1.x` - Initial development releases - Focus on core protocol implementation and OpenSSL-based crypto - Full NIP-01, NIP-04, NIP-05, NIP-06, NIP-11, NIP-13, NIP-17, NIP-19, NIP-42, NIP-44, NIP-59 support ## ๐Ÿ› Troubleshooting ### Common Issues **Build fails with secp256k1 errors:** ```bash cd secp256k1 ./autogen.sh ./configure --enable-module-schnorrsig --enable-module-ecdh make cd .. ./build.sh lib ``` **Library too large:** The x64 library is intentionally large (~15MB) because it includes all secp256k1 cryptographic functions and OpenSSL for complete self-containment. The ARM64 library is smaller (~2.4MB) as it links against system OpenSSL. **Linking errors:** Make sure to include the math library: ```bash gcc your_code.c ./libnostr_core.a -lm # Note the -lm flag ``` ### Getting Help - Check the `examples/` directory for working code - Run `./build.sh test` to verify your environment - Review the comprehensive API documentation in `nostr_core/nostr_core.h` ## ๐Ÿ“œ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## ๐Ÿ™ Acknowledgments - **NOSTR Protocol** - The decentralized social media protocol - **OpenSSL** - Production-grade cryptographic library and TLS implementation - **secp256k1** - Bitcoin's elliptic curve library - **cJSON** - Lightweight JSON parser - **curl** - HTTP/HTTPS client library for NIP-05/NIP-11 - **NOSTR Community** - For protocol specification and feedback --- **Built with โค๏ธ for the decentralized web** *OpenSSL-based โ€ข Minimal dependencies โ€ข Work in progress*