First commit on a late git install
This commit is contained in:
84
examples/input_detection.c
Normal file
84
examples/input_detection.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Example: Input Type Detection
|
||||
* Demonstrates nostr_detect_input_type() and nostr_decode_nsec()
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("=== NOSTR Input Type Detection Example ===\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test various input types
|
||||
const char* test_inputs[] = {
|
||||
// Mnemonic
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
|
||||
// Hex nsec (64 chars)
|
||||
"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
|
||||
|
||||
// Bech32 nsec
|
||||
"nsec1tkks0lxyf9x2jetlzluxsqqwudlnwvef9xx2muxvt7tsh7lgmrhqvfmaqg",
|
||||
|
||||
// Invalid input
|
||||
"not-a-valid-input",
|
||||
|
||||
// Empty string
|
||||
""
|
||||
};
|
||||
|
||||
const char* type_names[] = {
|
||||
"UNKNOWN",
|
||||
"MNEMONIC",
|
||||
"HEX_NSEC",
|
||||
"BECH32_NSEC"
|
||||
};
|
||||
|
||||
int num_tests = sizeof(test_inputs) / sizeof(test_inputs[0]);
|
||||
|
||||
for (int i = 0; i < num_tests; i++) {
|
||||
printf("Test %d:\n", i + 1);
|
||||
printf("Input: \"%s\"\n", test_inputs[i]);
|
||||
|
||||
// Detect input type
|
||||
nostr_input_type_t type = nostr_detect_input_type(test_inputs[i]);
|
||||
printf("Detected Type: %s\n", type_names[type]);
|
||||
|
||||
// Try to decode if it's an nsec
|
||||
if (type == NOSTR_INPUT_NSEC_HEX || type == NOSTR_INPUT_NSEC_BECH32) {
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
int result = nostr_decode_nsec(test_inputs[i], private_key);
|
||||
|
||||
if (result == NOSTR_SUCCESS) {
|
||||
// Convert back to hex and bech32 to verify
|
||||
char private_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char nsec_bech32[NOSTR_BECH32_KEY_SIZE];
|
||||
|
||||
nostr_bytes_to_hex(private_key, NOSTR_PRIVATE_KEY_SIZE, private_hex);
|
||||
nostr_key_to_bech32(private_key, "nsec", nsec_bech32);
|
||||
|
||||
printf("✓ Successfully decoded nsec!\n");
|
||||
printf(" Hex format: %s\n", private_hex);
|
||||
printf(" Bech32 format: %s\n", nsec_bech32);
|
||||
} else {
|
||||
printf("✗ Failed to decode nsec: %s\n", nostr_strerror(result));
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("✓ Example completed successfully!\n");
|
||||
printf("💡 Input detection helps handle different key formats automatically\n");
|
||||
return 0;
|
||||
}
|
||||
39
examples/integration_example/CMakeLists.txt
Normal file
39
examples/integration_example/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# Example CMakeLists.txt for a project using nostr_core library
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(my_nostr_app VERSION 1.0.0 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
# Method 1: Find installed package
|
||||
# Uncomment if nostr_core is installed system-wide
|
||||
# find_package(nostr_core REQUIRED)
|
||||
|
||||
# Method 2: Use as subdirectory
|
||||
# Uncomment if nostr_core is a subdirectory
|
||||
# add_subdirectory(nostr_core)
|
||||
|
||||
# Method 3: Use pkg-config
|
||||
# Uncomment if using pkg-config
|
||||
# find_package(PkgConfig REQUIRED)
|
||||
# pkg_check_modules(NOSTR_CORE REQUIRED nostr_core)
|
||||
|
||||
# Create executable
|
||||
add_executable(my_nostr_app main.c)
|
||||
|
||||
# Link with nostr_core
|
||||
# Choose one of the following based on your integration method:
|
||||
|
||||
# Method 1: Installed package
|
||||
# target_link_libraries(my_nostr_app nostr_core::static)
|
||||
|
||||
# Method 2: Subdirectory
|
||||
# target_link_libraries(my_nostr_app nostr_core_static)
|
||||
|
||||
# Method 3: pkg-config
|
||||
# target_include_directories(my_nostr_app PRIVATE ${NOSTR_CORE_INCLUDE_DIRS})
|
||||
# target_link_libraries(my_nostr_app ${NOSTR_CORE_LIBRARIES})
|
||||
|
||||
# For this example, we'll assume Method 2 (subdirectory)
|
||||
# Add the parent nostr_core directory
|
||||
add_subdirectory(../.. nostr_core)
|
||||
target_link_libraries(my_nostr_app nostr_core_static)
|
||||
186
examples/integration_example/README.md
Normal file
186
examples/integration_example/README.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# NOSTR Core Integration Example
|
||||
|
||||
This directory contains a complete example showing how to integrate the NOSTR Core library into your own projects.
|
||||
|
||||
## What This Example Demonstrates
|
||||
|
||||
- **Library Initialization**: Proper setup and cleanup of the NOSTR library
|
||||
- **Identity Management**: Key generation, bech32 encoding, and format detection
|
||||
- **Event Creation**: Creating and signing different types of NOSTR events
|
||||
- **Input Handling**: Processing various input formats (mnemonic, hex, bech32)
|
||||
- **Utility Functions**: Using helper functions for hex conversion and error handling
|
||||
- **CMake Integration**: How to integrate the library in your CMake-based project
|
||||
|
||||
## Building and Running
|
||||
|
||||
### Method 1: Using CMake
|
||||
|
||||
```bash
|
||||
# Create build directory
|
||||
mkdir build && cd build
|
||||
|
||||
# Configure with CMake
|
||||
cmake ..
|
||||
|
||||
# Build
|
||||
make
|
||||
|
||||
# Run the example
|
||||
./my_nostr_app
|
||||
```
|
||||
|
||||
### Method 2: Manual Compilation
|
||||
|
||||
```bash
|
||||
# Compile directly (assuming you're in the c_nostr root directory)
|
||||
gcc -I. examples/integration_example/main.c nostr_core.c nostr_crypto.c cjson/cJSON.c -lm -o integration_example
|
||||
|
||||
# Run
|
||||
./integration_example
|
||||
```
|
||||
|
||||
## Expected Output
|
||||
|
||||
The example will demonstrate:
|
||||
|
||||
1. **Identity Management Demo**
|
||||
- Generate a new keypair
|
||||
- Display keys in hex and bech32 format
|
||||
|
||||
2. **Event Creation Demo**
|
||||
- Create a text note event
|
||||
- Create a profile event
|
||||
- Display the JSON for both events
|
||||
|
||||
3. **Input Handling Demo**
|
||||
- Process different input formats
|
||||
- Show format detection and decoding
|
||||
|
||||
4. **Utility Functions Demo**
|
||||
- Hex conversion round-trip
|
||||
- Error message display
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
### Pattern 1: CMake Find Package
|
||||
|
||||
If NOSTR Core is installed system-wide:
|
||||
|
||||
```cmake
|
||||
find_package(nostr_core REQUIRED)
|
||||
target_link_libraries(your_app nostr_core::static)
|
||||
```
|
||||
|
||||
### Pattern 2: CMake Subdirectory
|
||||
|
||||
If NOSTR Core is a subdirectory of your project:
|
||||
|
||||
```cmake
|
||||
add_subdirectory(nostr_core)
|
||||
target_link_libraries(your_app nostr_core_static)
|
||||
```
|
||||
|
||||
### Pattern 3: pkg-config
|
||||
|
||||
If using pkg-config:
|
||||
|
||||
```cmake
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(NOSTR_CORE REQUIRED nostr_core)
|
||||
target_include_directories(your_app PRIVATE ${NOSTR_CORE_INCLUDE_DIRS})
|
||||
target_link_libraries(your_app ${NOSTR_CORE_LIBRARIES})
|
||||
```
|
||||
|
||||
### Pattern 4: Direct Source Integration
|
||||
|
||||
Copy the essential files to your project:
|
||||
|
||||
```bash
|
||||
cp nostr_core.{c,h} nostr_crypto.{c,h} your_project/src/
|
||||
cp -r cjson/ your_project/src/
|
||||
```
|
||||
|
||||
Then compile them with your project sources.
|
||||
|
||||
## Code Structure
|
||||
|
||||
### main.c Structure
|
||||
|
||||
The example is organized into clear demonstration functions:
|
||||
|
||||
- `demo_identity_management()` - Key generation and encoding
|
||||
- `demo_event_creation()` - Creating different event types
|
||||
- `demo_input_handling()` - Processing various input formats
|
||||
- `demo_utilities()` - Using utility functions
|
||||
|
||||
Each function demonstrates specific aspects of the library while maintaining proper error handling and resource cleanup.
|
||||
|
||||
### Key Integration Points
|
||||
|
||||
1. **Initialization**
|
||||
```c
|
||||
int ret = nostr_init();
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
2. **Resource Cleanup**
|
||||
```c
|
||||
// Always clean up JSON objects
|
||||
cJSON_Delete(event);
|
||||
|
||||
// Clean up library on exit
|
||||
nostr_cleanup();
|
||||
```
|
||||
|
||||
3. **Error Handling**
|
||||
```c
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Error: %s\n", nostr_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
You can modify this example for your specific needs:
|
||||
|
||||
- Change the `app_config_t` structure to match your application's configuration
|
||||
- Add additional event types or custom event creation logic
|
||||
- Integrate with your existing error handling and logging systems
|
||||
- Add networking functionality using the WebSocket layer
|
||||
|
||||
## Dependencies
|
||||
|
||||
This example requires:
|
||||
- C99 compiler (gcc, clang)
|
||||
- CMake 3.12+ (for CMake build)
|
||||
- NOSTR Core library and its dependencies
|
||||
|
||||
## Testing
|
||||
|
||||
You can test different input formats by passing them as command line arguments:
|
||||
|
||||
```bash
|
||||
# Test with mnemonic
|
||||
./my_nostr_app "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||
|
||||
# Test with hex private key
|
||||
./my_nostr_app "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
||||
# Test with bech32 nsec
|
||||
./my_nostr_app "nsec1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After studying this example, you can:
|
||||
|
||||
1. Integrate the patterns into your own application
|
||||
2. Explore the WebSocket functionality for relay communication
|
||||
3. Add support for additional NOSTR event types
|
||||
4. Implement your own identity persistence layer
|
||||
5. Add networking and relay management features
|
||||
|
||||
For more examples, see the other files in the `examples/` directory.
|
||||
271
examples/integration_example/main.c
Normal file
271
examples/integration_example/main.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Example application demonstrating how to integrate nostr_core into other projects
|
||||
* This shows a complete workflow from key generation to event publishing
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
// Example application configuration
|
||||
typedef struct {
|
||||
char* app_name;
|
||||
char* version;
|
||||
int debug_mode;
|
||||
} app_config_t;
|
||||
|
||||
static app_config_t g_config = {
|
||||
.app_name = "My NOSTR App",
|
||||
.version = "1.0.0",
|
||||
.debug_mode = 1
|
||||
};
|
||||
|
||||
// Helper function to print hex data
|
||||
static void print_hex(const char* label, const unsigned char* data, size_t len) {
|
||||
if (g_config.debug_mode) {
|
||||
printf("%s: ", label);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
printf("%02x", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to print JSON nicely
|
||||
static void print_event(const char* label, cJSON* event) {
|
||||
if (!event) {
|
||||
printf("%s: NULL\n", label);
|
||||
return;
|
||||
}
|
||||
|
||||
char* json_string = cJSON_Print(event);
|
||||
if (json_string) {
|
||||
printf("%s:\n%s\n", label, json_string);
|
||||
free(json_string);
|
||||
}
|
||||
}
|
||||
|
||||
// Example: Generate and manage identity
|
||||
static int demo_identity_management(void) {
|
||||
printf("\n=== Identity Management Demo ===\n");
|
||||
|
||||
unsigned char private_key[32], public_key[32];
|
||||
char nsec[100], npub[100];
|
||||
|
||||
// Generate a new keypair
|
||||
printf("Generating new keypair...\n");
|
||||
int ret = nostr_generate_keypair(private_key, public_key);
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Error generating keypair: %s\n", nostr_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
print_hex("Private Key", private_key, 32);
|
||||
print_hex("Public Key", public_key, 32);
|
||||
|
||||
// Convert to bech32 format
|
||||
ret = nostr_key_to_bech32(private_key, "nsec", nsec);
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Error encoding nsec: %s\n", nostr_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nostr_key_to_bech32(public_key, "npub", npub);
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Error encoding npub: %s\n", nostr_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("nsec: %s\n", nsec);
|
||||
printf("npub: %s\n", npub);
|
||||
|
||||
return NOSTR_SUCCESS;
|
||||
}
|
||||
|
||||
// Example: Create different types of events
|
||||
static int demo_event_creation(const unsigned char* private_key) {
|
||||
printf("\n=== Event Creation Demo ===\n");
|
||||
|
||||
// Create a text note
|
||||
printf("Creating text note...\n");
|
||||
cJSON* text_event = nostr_create_text_event("Hello from my NOSTR app!", private_key);
|
||||
if (!text_event) {
|
||||
printf("Error creating text event\n");
|
||||
return NOSTR_ERROR_JSON_PARSE;
|
||||
}
|
||||
print_event("Text Event", text_event);
|
||||
|
||||
// Create a profile event
|
||||
printf("\nCreating profile event...\n");
|
||||
cJSON* profile_event = nostr_create_profile_event(
|
||||
g_config.app_name,
|
||||
"A sample application demonstrating NOSTR integration",
|
||||
private_key
|
||||
);
|
||||
if (!profile_event) {
|
||||
printf("Error creating profile event\n");
|
||||
cJSON_Delete(text_event);
|
||||
return NOSTR_ERROR_JSON_PARSE;
|
||||
}
|
||||
print_event("Profile Event", profile_event);
|
||||
|
||||
// Cleanup
|
||||
cJSON_Delete(text_event);
|
||||
cJSON_Delete(profile_event);
|
||||
|
||||
return NOSTR_SUCCESS;
|
||||
}
|
||||
|
||||
// Example: Handle different input formats
|
||||
static int demo_input_handling(const char* user_input) {
|
||||
printf("\n=== Input Handling Demo ===\n");
|
||||
printf("Processing input: %s\n", user_input);
|
||||
|
||||
// Detect input type
|
||||
int input_type = nostr_detect_input_type(user_input);
|
||||
switch (input_type) {
|
||||
case NOSTR_INPUT_MNEMONIC:
|
||||
printf("Detected: BIP39 Mnemonic\n");
|
||||
{
|
||||
unsigned char priv[32], pub[32];
|
||||
int ret = nostr_derive_keys_from_mnemonic(user_input, 0, priv, pub);
|
||||
if (ret == NOSTR_SUCCESS) {
|
||||
print_hex("Derived Private Key", priv, 32);
|
||||
print_hex("Derived Public Key", pub, 32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NOSTR_INPUT_NSEC_HEX:
|
||||
printf("Detected: Hex-encoded private key\n");
|
||||
{
|
||||
unsigned char decoded[32];
|
||||
int ret = nostr_decode_nsec(user_input, decoded);
|
||||
if (ret == NOSTR_SUCCESS) {
|
||||
print_hex("Decoded Private Key", decoded, 32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NOSTR_INPUT_NSEC_BECH32:
|
||||
printf("Detected: Bech32-encoded private key (nsec)\n");
|
||||
{
|
||||
unsigned char decoded[32];
|
||||
int ret = nostr_decode_nsec(user_input, decoded);
|
||||
if (ret == NOSTR_SUCCESS) {
|
||||
print_hex("Decoded Private Key", decoded, 32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown input format\n");
|
||||
return NOSTR_ERROR_INVALID_INPUT;
|
||||
}
|
||||
|
||||
return NOSTR_SUCCESS;
|
||||
}
|
||||
|
||||
// Example: Demonstrate utility functions
|
||||
static int demo_utilities(void) {
|
||||
printf("\n=== Utility Functions Demo ===\n");
|
||||
|
||||
// Hex conversion
|
||||
const char* test_hex = "deadbeef";
|
||||
unsigned char bytes[4];
|
||||
char hex_result[9];
|
||||
|
||||
printf("Testing hex conversion with: %s\n", test_hex);
|
||||
|
||||
int ret = nostr_hex_to_bytes(test_hex, bytes, 4);
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Error in hex_to_bytes: %s\n", nostr_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
nostr_bytes_to_hex(bytes, 4, hex_result);
|
||||
printf("Round-trip result: %s\n", hex_result);
|
||||
|
||||
// Error message testing
|
||||
printf("\nTesting error messages:\n");
|
||||
for (int i = 0; i >= -10; i--) {
|
||||
const char* msg = nostr_strerror(i);
|
||||
if (msg && strlen(msg) > 0) {
|
||||
printf(" %d: %s\n", i, msg);
|
||||
}
|
||||
}
|
||||
|
||||
return NOSTR_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
printf("%s v%s\n", g_config.app_name, g_config.version);
|
||||
printf("NOSTR Core Integration Example\n");
|
||||
printf("=====================================\n");
|
||||
|
||||
// Initialize the NOSTR library
|
||||
printf("Initializing NOSTR core library...\n");
|
||||
int ret = nostr_init();
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
printf("Failed to initialize NOSTR library: %s\n", nostr_strerror(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run demonstrations
|
||||
unsigned char demo_private_key[32];
|
||||
|
||||
// 1. Identity management
|
||||
ret = demo_identity_management();
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Generate a key for other demos
|
||||
nostr_generate_keypair(demo_private_key, NULL);
|
||||
|
||||
// 2. Event creation
|
||||
ret = demo_event_creation(demo_private_key);
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// 3. Input handling (use command line argument if provided)
|
||||
const char* test_input = (argc > 1) ? argv[1] :
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||
ret = demo_input_handling(test_input);
|
||||
if (ret != NOSTR_SUCCESS && ret != NOSTR_ERROR_INVALID_INPUT) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// 4. Utility functions
|
||||
ret = demo_utilities();
|
||||
if (ret != NOSTR_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("\n=====================================\n");
|
||||
printf("All demonstrations completed successfully!\n");
|
||||
printf("\nThis example shows how to:\n");
|
||||
printf(" • Initialize the NOSTR library\n");
|
||||
printf(" • Generate and manage keypairs\n");
|
||||
printf(" • Create and sign different event types\n");
|
||||
printf(" • Handle various input formats\n");
|
||||
printf(" • Use utility functions\n");
|
||||
printf(" • Clean up resources properly\n");
|
||||
|
||||
ret = NOSTR_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
// Clean up the NOSTR library
|
||||
printf("\nCleaning up NOSTR library...\n");
|
||||
nostr_cleanup();
|
||||
|
||||
if (ret == NOSTR_SUCCESS) {
|
||||
printf("Example completed successfully.\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("Example failed with error: %s\n", nostr_strerror(ret));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
56
examples/keypair_generation.c
Normal file
56
examples/keypair_generation.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Example: Random Keypair Generation
|
||||
* Demonstrates nostr_generate_keypair()
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("=== NOSTR Random Keypair Generation Example ===\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Generate a random keypair
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char public_key[NOSTR_PUBLIC_KEY_SIZE];
|
||||
|
||||
int result = nostr_generate_keypair(private_key, public_key);
|
||||
if (result != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to generate keypair: %s\n", nostr_strerror(result));
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert to hex format
|
||||
char private_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char public_hex[NOSTR_HEX_KEY_SIZE];
|
||||
|
||||
nostr_bytes_to_hex(private_key, NOSTR_PRIVATE_KEY_SIZE, private_hex);
|
||||
nostr_bytes_to_hex(public_key, NOSTR_PUBLIC_KEY_SIZE, public_hex);
|
||||
|
||||
// Convert to bech32 format
|
||||
char nsec[NOSTR_BECH32_KEY_SIZE];
|
||||
char npub[NOSTR_BECH32_KEY_SIZE];
|
||||
|
||||
nostr_key_to_bech32(private_key, "nsec", nsec);
|
||||
nostr_key_to_bech32(public_key, "npub", npub);
|
||||
|
||||
// Display results
|
||||
printf("✓ Successfully generated random NOSTR keypair\n\n");
|
||||
printf("Private Key (hex): %s\n", private_hex);
|
||||
printf("Public Key (hex): %s\n", public_hex);
|
||||
printf("nsec (bech32): %s\n", nsec);
|
||||
printf("npub (bech32): %s\n", npub);
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("\n✓ Example completed successfully!\n");
|
||||
return 0;
|
||||
}
|
||||
57
examples/mnemonic_derivation.c
Normal file
57
examples/mnemonic_derivation.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Example: Key Derivation from Existing Mnemonic
|
||||
* Demonstrates nostr_derive_keys_from_mnemonic()
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("=== NOSTR Key Derivation from Mnemonic Example ===\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Use a well-known test mnemonic
|
||||
const char* test_mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||
|
||||
printf("Using test mnemonic: %s\n\n", test_mnemonic);
|
||||
|
||||
// Derive keys for multiple accounts
|
||||
for (int account = 0; account < 3; account++) {
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char public_key[NOSTR_PUBLIC_KEY_SIZE];
|
||||
|
||||
int result = nostr_derive_keys_from_mnemonic(test_mnemonic, account,
|
||||
private_key, public_key);
|
||||
if (result != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to derive keys for account %d: %s\n",
|
||||
account, nostr_strerror(result));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert to bech32 format
|
||||
char nsec[NOSTR_BECH32_KEY_SIZE];
|
||||
char npub[NOSTR_BECH32_KEY_SIZE];
|
||||
|
||||
nostr_key_to_bech32(private_key, "nsec", nsec);
|
||||
nostr_key_to_bech32(public_key, "npub", npub);
|
||||
|
||||
// Display results for this account
|
||||
printf("Account %d (m/44'/1237'/%d'/0/0):\n", account, account);
|
||||
printf(" nsec: %s\n", nsec);
|
||||
printf(" npub: %s\n", npub);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("✓ Example completed successfully!\n");
|
||||
printf("💡 The same mnemonic always produces the same keys (deterministic)\n");
|
||||
return 0;
|
||||
}
|
||||
60
examples/mnemonic_generation.c
Normal file
60
examples/mnemonic_generation.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Example: Mnemonic Generation and Key Derivation
|
||||
* Demonstrates nostr_generate_mnemonic_and_keys()
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("=== NOSTR Mnemonic Generation Example ===\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Generate mnemonic and derive keys for account 0
|
||||
char mnemonic[256];
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char public_key[NOSTR_PUBLIC_KEY_SIZE];
|
||||
int account = 0;
|
||||
|
||||
int result = nostr_generate_mnemonic_and_keys(mnemonic, sizeof(mnemonic),
|
||||
account, private_key, public_key);
|
||||
if (result != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to generate mnemonic and keys: %s\n", nostr_strerror(result));
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert keys to various formats
|
||||
char private_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char public_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char nsec[NOSTR_BECH32_KEY_SIZE];
|
||||
char npub[NOSTR_BECH32_KEY_SIZE];
|
||||
|
||||
nostr_bytes_to_hex(private_key, NOSTR_PRIVATE_KEY_SIZE, private_hex);
|
||||
nostr_bytes_to_hex(public_key, NOSTR_PUBLIC_KEY_SIZE, public_hex);
|
||||
nostr_key_to_bech32(private_key, "nsec", nsec);
|
||||
nostr_key_to_bech32(public_key, "npub", npub);
|
||||
|
||||
// Display results
|
||||
printf("✓ Successfully generated BIP39 mnemonic and derived NOSTR keys\n\n");
|
||||
printf("BIP39 Mnemonic: %s\n\n", mnemonic);
|
||||
printf("Account: %d\n", account);
|
||||
printf("Derivation Path: m/44'/1237'/%d'/0/0 (NIP-06)\n\n", account);
|
||||
printf("Private Key (hex): %s\n", private_hex);
|
||||
printf("Public Key (hex): %s\n", public_hex);
|
||||
printf("nsec (bech32): %s\n", nsec);
|
||||
printf("npub (bech32): %s\n", npub);
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("\n✓ Example completed successfully!\n");
|
||||
printf("💡 Save the mnemonic safely - it can restore your NOSTR identity\n");
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/simple_keygen
Executable file
BIN
examples/simple_keygen
Executable file
Binary file not shown.
95
examples/simple_keygen.c
Normal file
95
examples/simple_keygen.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Simple Key Generation Example
|
||||
*
|
||||
* This example demonstrates basic NOSTR key generation using the nostr_core library.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("NOSTR Core Library - Simple Key Generation Example\n");
|
||||
printf("==================================================\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR core library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("✓ NOSTR core library initialized\n\n");
|
||||
|
||||
// Generate a random keypair
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char public_key[NOSTR_PUBLIC_KEY_SIZE];
|
||||
|
||||
printf("Generating random NOSTR keypair...\n");
|
||||
int result = nostr_generate_keypair(private_key, public_key);
|
||||
|
||||
if (result != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to generate keypair: %s\n", nostr_strerror(result));
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Convert keys to hex format
|
||||
char private_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char public_hex[NOSTR_HEX_KEY_SIZE];
|
||||
|
||||
nostr_bytes_to_hex(private_key, NOSTR_PRIVATE_KEY_SIZE, private_hex);
|
||||
nostr_bytes_to_hex(public_key, NOSTR_PUBLIC_KEY_SIZE, public_hex);
|
||||
|
||||
// Convert keys to bech32 format
|
||||
char nsec_bech32[NOSTR_BECH32_KEY_SIZE];
|
||||
char npub_bech32[NOSTR_BECH32_KEY_SIZE];
|
||||
|
||||
if (nostr_key_to_bech32(private_key, "nsec", nsec_bech32) != NOSTR_SUCCESS ||
|
||||
nostr_key_to_bech32(public_key, "npub", npub_bech32) != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to convert keys to bech32 format\n");
|
||||
nostr_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Display the generated keys
|
||||
printf("✓ Keypair generated successfully!\n\n");
|
||||
printf("Private Key (hex): %s\n", private_hex);
|
||||
printf("Public Key (hex): %s\n", public_hex);
|
||||
printf("nsec (bech32): %s\n", nsec_bech32);
|
||||
printf("npub (bech32): %s\n", npub_bech32);
|
||||
|
||||
printf("\n=== Key Validation Test ===\n");
|
||||
|
||||
// Test key validation by decoding the generated nsec
|
||||
unsigned char decoded_private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
result = nostr_decode_nsec(nsec_bech32, decoded_private_key);
|
||||
|
||||
if (result == NOSTR_SUCCESS) {
|
||||
printf("✓ nsec validation: PASSED\n");
|
||||
|
||||
// Verify the decoded key matches the original
|
||||
int keys_match = 1;
|
||||
for (int i = 0; i < NOSTR_PRIVATE_KEY_SIZE; i++) {
|
||||
if (private_key[i] != decoded_private_key[i]) {
|
||||
keys_match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys_match) {
|
||||
printf("✓ Key consistency: PASSED\n");
|
||||
} else {
|
||||
printf("✗ Key consistency: FAILED\n");
|
||||
}
|
||||
} else {
|
||||
printf("✗ nsec validation: FAILED (%s)\n", nostr_strerror(result));
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("\nExample completed successfully!\n");
|
||||
printf("You can now use these keys with NOSTR applications.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
165
examples/utility_functions.c
Normal file
165
examples/utility_functions.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Example: Utility Functions
|
||||
* Demonstrates nostr_bytes_to_hex(), nostr_hex_to_bytes(), nostr_strerror()
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nostr_core.h"
|
||||
|
||||
int main() {
|
||||
printf("=== NOSTR Utility Functions Example ===\n\n");
|
||||
|
||||
// Initialize the library
|
||||
if (nostr_init() != NOSTR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize NOSTR library\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test 1: Bytes to Hex conversion
|
||||
printf("Test 1: Bytes to Hex Conversion\n");
|
||||
printf("-------------------------------\n");
|
||||
|
||||
unsigned char test_bytes[] = {
|
||||
0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b,
|
||||
0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6,
|
||||
0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd,
|
||||
0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb
|
||||
};
|
||||
|
||||
char hex_output[65]; // 32 bytes * 2 + null terminator
|
||||
nostr_bytes_to_hex(test_bytes, sizeof(test_bytes), hex_output);
|
||||
|
||||
printf("Input bytes (%zu bytes):\n", sizeof(test_bytes));
|
||||
printf(" ");
|
||||
for (size_t i = 0; i < sizeof(test_bytes); i++) {
|
||||
printf("%02x ", test_bytes[i]);
|
||||
if ((i + 1) % 16 == 0) printf("\n ");
|
||||
}
|
||||
printf("\n");
|
||||
printf("Hex output: %s\n\n", hex_output);
|
||||
|
||||
// Test 2: Hex to Bytes conversion
|
||||
printf("Test 2: Hex to Bytes Conversion\n");
|
||||
printf("-------------------------------\n");
|
||||
|
||||
const char* test_hex = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb";
|
||||
unsigned char bytes_output[32];
|
||||
|
||||
printf("Input hex: %s\n", test_hex);
|
||||
|
||||
int result = nostr_hex_to_bytes(test_hex, bytes_output, sizeof(bytes_output));
|
||||
if (result == NOSTR_SUCCESS) {
|
||||
printf("✓ Successfully converted hex to bytes\n");
|
||||
printf("Output bytes (%zu bytes):\n", sizeof(bytes_output));
|
||||
printf(" ");
|
||||
for (size_t i = 0; i < sizeof(bytes_output); i++) {
|
||||
printf("%02x ", bytes_output[i]);
|
||||
if ((i + 1) % 16 == 0) printf("\n ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Verify round-trip conversion
|
||||
int match = memcmp(test_bytes, bytes_output, sizeof(test_bytes)) == 0;
|
||||
printf("Round-trip verification: %s\n\n", match ? "✓ PASSED" : "✗ FAILED");
|
||||
} else {
|
||||
printf("✗ Failed to convert hex to bytes: %s\n\n", nostr_strerror(result));
|
||||
}
|
||||
|
||||
// Test 3: Error code to string conversion
|
||||
printf("Test 3: Error Code to String Conversion\n");
|
||||
printf("---------------------------------------\n");
|
||||
|
||||
int error_codes[] = {
|
||||
NOSTR_SUCCESS,
|
||||
NOSTR_ERROR_INVALID_INPUT,
|
||||
NOSTR_ERROR_CRYPTO_FAILED,
|
||||
NOSTR_ERROR_MEMORY_FAILED,
|
||||
NOSTR_ERROR_IO_FAILED,
|
||||
NOSTR_ERROR_NETWORK_FAILED,
|
||||
-999 // Unknown error code
|
||||
};
|
||||
|
||||
int num_errors = sizeof(error_codes) / sizeof(error_codes[0]);
|
||||
|
||||
for (int i = 0; i < num_errors; i++) {
|
||||
int code = error_codes[i];
|
||||
const char* message = nostr_strerror(code);
|
||||
printf("Error code %d: %s\n", code, message);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Test 4: Invalid hex string handling
|
||||
printf("Test 4: Invalid Hex String Handling\n");
|
||||
printf("------------------------------------\n");
|
||||
|
||||
const char* invalid_hex_strings[] = {
|
||||
"invalid_hex_string", // Non-hex characters
|
||||
"5dab087e624a8a4b79e17f8b", // Too short (24 chars, need 64)
|
||||
"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0ebaa", // Too long (66 chars)
|
||||
"", // Empty string
|
||||
"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eZ" // Invalid hex char 'Z'
|
||||
};
|
||||
|
||||
int num_invalid = sizeof(invalid_hex_strings) / sizeof(invalid_hex_strings[0]);
|
||||
|
||||
for (int i = 0; i < num_invalid; i++) {
|
||||
printf("Testing invalid hex: \"%s\"\n", invalid_hex_strings[i]);
|
||||
|
||||
unsigned char invalid_output[32];
|
||||
result = nostr_hex_to_bytes(invalid_hex_strings[i], invalid_output, sizeof(invalid_output));
|
||||
|
||||
if (result == NOSTR_SUCCESS) {
|
||||
printf(" ✗ Unexpectedly succeeded (should have failed)\n");
|
||||
} else {
|
||||
printf(" ✓ Correctly failed: %s\n", nostr_strerror(result));
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Test 5: Working with real NOSTR keys
|
||||
printf("Test 5: Real NOSTR Key Conversion\n");
|
||||
printf("---------------------------------\n");
|
||||
|
||||
// Generate a real keypair
|
||||
unsigned char private_key[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char public_key[NOSTR_PUBLIC_KEY_SIZE];
|
||||
|
||||
result = nostr_generate_keypair(private_key, public_key);
|
||||
if (result == NOSTR_SUCCESS) {
|
||||
// Convert to hex
|
||||
char private_hex[NOSTR_HEX_KEY_SIZE];
|
||||
char public_hex[NOSTR_HEX_KEY_SIZE];
|
||||
|
||||
nostr_bytes_to_hex(private_key, NOSTR_PRIVATE_KEY_SIZE, private_hex);
|
||||
nostr_bytes_to_hex(public_key, NOSTR_PUBLIC_KEY_SIZE, public_hex);
|
||||
|
||||
printf("Generated NOSTR keys:\n");
|
||||
printf("Private key (hex): %s\n", private_hex);
|
||||
printf("Public key (hex): %s\n", public_hex);
|
||||
|
||||
// Convert back to bytes to verify
|
||||
unsigned char recovered_private[NOSTR_PRIVATE_KEY_SIZE];
|
||||
unsigned char recovered_public[NOSTR_PUBLIC_KEY_SIZE];
|
||||
|
||||
int priv_result = nostr_hex_to_bytes(private_hex, recovered_private, NOSTR_PRIVATE_KEY_SIZE);
|
||||
int pub_result = nostr_hex_to_bytes(public_hex, recovered_public, NOSTR_PUBLIC_KEY_SIZE);
|
||||
|
||||
if (priv_result == NOSTR_SUCCESS && pub_result == NOSTR_SUCCESS) {
|
||||
int priv_match = memcmp(private_key, recovered_private, NOSTR_PRIVATE_KEY_SIZE) == 0;
|
||||
int pub_match = memcmp(public_key, recovered_public, NOSTR_PUBLIC_KEY_SIZE) == 0;
|
||||
|
||||
printf("Key recovery verification:\n");
|
||||
printf(" Private key: %s\n", priv_match ? "✓ PASSED" : "✗ FAILED");
|
||||
printf(" Public key: %s\n", pub_match ? "✓ PASSED" : "✗ FAILED");
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
nostr_cleanup();
|
||||
|
||||
printf("\n✓ Example completed successfully!\n");
|
||||
printf("💡 Utility functions handle format conversions and error reporting\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user