Go to file
Laan Tungir c0784fc890 added nip 17 2025-10-04 18:32:28 -04:00
.clinerules Nostr note validation added to nip01 2025-08-19 06:59:04 -04:00
.vscode Last commit before switching from mbedtls to openssl 2025-08-14 09:58:24 -04:00
cjson Fix submodule compatibility: Remove version.c dependency and include cjson source files 2025-08-14 16:40:34 -04:00
examples Implement NIP-21: nostr: URI scheme with full support for note, nprofile, nevent, and naddr URIs including TLV encoding/decoding and comprehensive test suite 2025-10-03 06:10:56 -04:00
nostr_core added nip 17 2025-10-04 18:32:28 -04:00
nostr_websocket nip 17, and 59 2025-10-03 04:25:10 -04:00
tests Implement NIP-21: nostr: URI scheme with full support for note, nprofile, nevent, and naddr URIs including TLV encoding/decoding and comprehensive test suite 2025-10-03 06:10:56 -04:00
.gitignore Updated synchronous relay queries to handle nip42. 2025-09-30 12:16:23 -04:00
POOL_API.md Updated synchronous relay queries to handle nip42. 2025-09-30 12:16:23 -04:00
README.md added nip 17 2025-10-04 18:32:28 -04:00
VERSION added nip 17 2025-10-04 18:32:28 -04:00
build.sh added nip 17 2025-10-04 18:32:28 -04:00
debug.log Implement NIP-21: nostr: URI scheme with full support for note, nprofile, nevent, and naddr URIs including TLV encoding/decoding and comprehensive test suite 2025-10-03 06:10:56 -04:00
increment_and_push.sh nip 17, and 59 2025-10-03 04:25:10 -04:00
nostr_core_lib.code-workspace Updated synchronous relay queries to handle nip42. 2025-09-30 12:16:23 -04:00
package-lock.json First commit on a late git install 2025-08-09 10:23:28 -04:00
package.json Fixed error in nip04 implementation. Now working 2025-08-17 10:42:38 -04:00
pool.log Implement NIP-21: nostr: URI scheme with full support for note, nprofile, nevent, and naddr URIs including TLV encoding/decoding and comprehensive test suite 2025-10-03 06:10:56 -04:00
todo.md Nostr note validation added to nip01 2025-08-19 06:59:04 -04:00
websocket_debug nip 17, and 59 2025-10-03 04:25:10 -04:00

README.md

NOSTR Core Library

A C library for NOSTR protocol implementation. Work in progress.

Version License Build Status

📋 NIP Implementation Status

Core Protocol NIPs

  • NIP-01 - Basic protocol flow - event creation, signing, and validation
  • NIP-02 - Contact List and Petnames
  • NIP-03 - OpenTimestamps Attestations for Events
  • NIP-04 - Encrypted Direct Messages (legacy)
  • NIP-05 - Mapping Nostr keys to DNS-based internet identifiers
  • NIP-06 - Basic key derivation from mnemonic seed phrase
  • NIP-07 - window.nostr capability for web browsers
  • NIP-08 - Handling Mentions
  • NIP-09 - Event Deletion
  • NIP-10 - Conventions for clients' use of e and p tags in text events
  • NIP-11 - Relay Information Document
  • NIP-12 - Generic Tag Queries
  • NIP-13 - Proof of Work
  • NIP-14 - Subject tag in text events
  • NIP-15 - Nostr Marketplace (for resilient marketplaces)
  • NIP-16 - Event Treatment
  • NIP-17 - Private Direct Messages
  • NIP-18 - Reposts
  • NIP-19 - bech32-encoded entities
  • NIP-20 - Command Results
  • NIP-21 - nostr: URI scheme
  • NIP-22 - Event created_at Limits
  • NIP-23 - Long-form Content
  • NIP-24 - Extra metadata fields and tags
  • NIP-25 - Reactions
  • NIP-26 - Delegated Event Signing
  • NIP-27 - Text Note References
  • NIP-28 - Public Chat
  • NIP-29 - Relay-based Groups
  • NIP-30 - Custom Emoji
  • NIP-31 - Dealing with Unknown Events
  • NIP-32 - Labeling
  • NIP-33 - Parameterized Replaceable Events
  • NIP-34 - git stuff
  • NIP-35 - Torrents
  • NIP-36 - Sensitive Content / Content Warning
  • NIP-37 - Draft Events
  • NIP-38 - User Statuses
  • NIP-39 - External Identities in Profiles
  • NIP-40 - Expiration Timestamp
  • NIP-42 - Authentication of clients to relays
  • NIP-44 - Versioned Encryption
  • NIP-45 - Counting results
  • NIP-46 - Nostr Connect
  • NIP-47 - Wallet Connect
  • NIP-48 - Proxy Tags
  • NIP-49 - Private Key Encryption
  • NIP-50 - Search Capability
  • NIP-51 - Lists
  • NIP-52 - Calendar Events
  • NIP-53 - Live Activities
  • NIP-54 - Wiki
  • NIP-55 - Android Signer Application
  • NIP-56 - Reporting
  • NIP-57 - Lightning Zaps
  • NIP-58 - Badges
  • NIP-59 - Gift Wrap
  • NIP-60 - Cashu Wallet
  • NIP-61 - Nutzaps
  • NIP-62 - Log events
  • NIP-64 - Chess (PGN)
  • NIP-65 - Relay List Metadata
  • NIP-66 - Relay Monitor
  • NIP-68 - Web badges
  • NIP-69 - Peer-to-peer Order events
  • NIP-70 - Protected Events
  • NIP-71 - Video Events
  • NIP-72 - Moderated Communities
  • NIP-73 - External Content IDs
  • NIP-75 - Zap Goals
  • NIP-77 - Arbitrary custom app data
  • NIP-78 - Application-specific data
  • NIP-84 - Highlights
  • NIP-86 - Relay Management API
  • NIP-87 - Relay List Recommendations
  • NIP-88 - Stella: A Stellar Relay
  • NIP-89 - Recommended Application Handlers
  • NIP-90 - Data Vending Machines
  • NIP-92 - Media Attachments
  • NIP-94 - File Metadata
  • NIP-96 - HTTP File Storage Integration
  • NIP-98 - HTTP Auth
  • NIP-99 - 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:

    git clone https://github.com/yourusername/nostr_core_lib.git
    cd nostr_core_lib
    
  2. Build the library:

    ./build.sh lib
    
  3. Run examples:

    ./build.sh examples
    ./examples/simple_keygen
    

Usage Example

#include "nostr_core/nostr_core.h"
#include <stdio.h>

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:

gcc example.c -o example ./libnostr_core.a -lm
./example

🏗️ Building

Build Targets

./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

# 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:

sudo apt install build-essential libssl-dev libcurl4-openssl-dev libsecp256k1-dev

Install on CentOS/RHEL:

sudo yum install gcc openssl-devel libcurl-devel libsecp256k1-devel

Install on macOS:

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

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

// 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

// 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)

// 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

// 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)

// 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

// 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

// 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:

./build.sh examples
ls -la examples/

🧪 Testing

The library includes extensive tests:

# 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

  1. Install system dependencies first (see Dependencies section above)

  2. Copy required files to your project:

    cp libnostr_core.a /path/to/your/project/
    cp nostr_core/nostr_core.h /path/to/your/project/
    
  3. Link in your project:

    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:

    cp -r nostr_core/ /path/to/your/project/
    cp -r cjson/ /path/to/your/project/
    
  3. Include in your build:

    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:

gcc your_app.c ./libnostr_core.a -lssl -lcrypto -lcurl -lsecp256k1 -lm -o your_app

Check system dependencies:

ldd your_app  # Shows linked system libraries

🔧 Configuration

Compile-Time Options

// 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

# 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

🤝 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:

# Install secp256k1 with Schnorr support
sudo apt install libsecp256k1-dev    # Ubuntu/Debian
# or
sudo yum install libsecp256k1-devel  # CentOS/RHEL
# or
brew install secp256k1               # macOS

# If still failing, build from source with Schnorr support:
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1
./autogen.sh
./configure --enable-module-schnorrsig --enable-module-ecdh
make
sudo make install

Library size: The library is small (~500KB) as it links against system libraries (secp256k1, OpenSSL, curl) rather than including them statically. This keeps the binary size manageable while maintaining full functionality.

Linking errors: Make sure to include the math library:

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 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