@candypoets/nipworker
v0.0.75
Published
Nostr client library with worker-based architecture using Rust WASM
Maintainers
Readme
@candypoets/nipworker
A high-performance Nostr client library with worker-based architecture using Rust WebAssembly for optimal performance and non-blocking operations.

🚀 Features
- High Performance: Rust WASM core for cryptographic operations and message processing
- Worker-Based Architecture: Non-blocking operations using Web Workers
- TypeScript Support: Full TypeScript definitions included
- Dual Module Support: Both ES modules and UMD builds
- Efficient Serialization: Uses MessagePack for optimal data transfer
- Comprehensive NIP Support: Implements 12+ standard Nostr Implementation Possibilities (NIPs)
📋 Supported NIPs
| NIP | Name | Description | Event Kinds | Status | |-----|------|-------------|-------------|---------| | NIP-01 | Basic Protocol | Core protocol flow description | 0, 1 | ✅ Full | | NIP-02 | Contact List | Contact lists and petnames | 3 | ✅ Full | | NIP-04 | Encrypted DMs | Encrypted direct messages | 4 | ✅ Full | | NIP-05 | DNS Identifiers | Mapping keys to DNS identifiers | - | 🔄 Partial | | NIP-10 | Text Note References | Threading and replies | - | ✅ Full | | NIP-18 | Reposts | Event reposts | 6 | ✅ Full | | NIP-19 | bech32 Entities | npub, note, nevent, nprofile encoding | - | ✅ Full | | NIP-25 | Reactions | Event reactions and emoji | 7 | ✅ Full | | NIP-27 | Text References | Mentions and references in content | - | ✅ Full | | NIP-44 | Versioned Encryption | Advanced encryption for private events | - | ✅ Full | | NIP-51 | Lists | Categorized lists (people, bookmarks) | 39089 | ✅ Full | | NIP-57 | Lightning Zaps | Bitcoin Lightning Network integration | 9735 | ✅ Full | | NIP-60 | Cashu Wallet | Cashu ecash wallet functionality | 7374, 7375, 7376, 10019, 17375 | ✅ Full | | NIP-61 | Nutzaps | Cashu token zaps | 9321 | ✅ Full | | NIP-65 | Relay Lists | User relay preferences | 10002 | ✅ Full |
NIP-60 Cashu Wallet Events
The library provides complete support for NIP-60 Cashu wallet functionality:
| Event Kind | Description | Encryption | Purpose | |------------|-------------|------------|---------| | 7374 | Quote events | NIP-44 | Token redemption quotes | | 7375 | Token events | NIP-44 | Cashu proofs and tokens | | 7376 | Spending history | NIP-44 | Transaction history | | 9321 | Nutzaps | - | Cashu token zaps | | 10019 | Wallet settings | - | User wallet preferences | | 17375 | Encrypted wallets | NIP-44 | Private wallet data |
Legend
- ✅ Full: Complete implementation with all features
- 🔄 Partial: Basic support, some features may be limited
- ❌ Not Supported: NIP is not implemented
📦 Installation
npm install @candypoets/nipworkerThat's it! No additional dependencies needed.
🔧 Usage
Import Structure
The library is organized into logical modules for better tree-shaking:
// Core API - main functionality
import { nostrManager, createNostrManager } from '@candypoets/nipworker';
// Hooks - React-style subscription hooks
import { useSubscription } from '@candypoets/nipworker/hooks';
// Types - TypeScript type definitions
import type {
ParsedEvent,
Kind1Parsed,
NostrManagerConfig,
Request
} from '@candypoets/nipworker/types';
// Utils - type guards and helper functions
import { isKind1, isKind0, SignerTypes } from '@candypoets/nipworker/utils';Basic Usage
import { nostrManager } from '@candypoets/nipworker';
import { useSubscription } from '@candypoets/nipworker/hooks';
// Login by setting up a signer (private key)
nostrManager.setSigner('privkey', 'your-private-key-hex');
// Subscribe to events using the hook
const unsubscribe = useSubscription(
'my-subscription',
[{
kinds: [1], // Text notes
limit: 10
}],
(events, eventType) => {
if (eventType === 'EVENTS') {
console.log('Received events:', events);
} else if (eventType === 'EOSE') {
console.log('End of stored events');
}
},
{ closeOnEose: false }
);
// Publish an event
const event = {
kind: 1,
content: 'Hello Nostr!',
tags: [],
created_at: Math.floor(Date.now() / 1000)
};
nostrManager.publish('publish-id-123', event, (status, type) => {
console.log('Publish status:', status);
});
// Clean up subscription when done
// unsubscribe();Advanced Usage
import { createNostrManager } from '@candypoets/nipworker';
import { useSubscription } from '@candypoets/nipworker/hooks';
// Create a custom manager instance with configuration
const customManager = createNostrManager();
// Set up multiple signers
customManager.setSigner('privkey', 'main-private-key-hex');
// Subscribe to specific authors with multiple filters
const unsubscribe = useSubscription(
'author-feed',
[
{
kinds: [1, 6, 7],
authors: ['pubkey1', 'pubkey2'],
since: Math.floor(Date.now() / 1000) - 3600, // Last hour
limit: 50
},
{
kinds: [30023], // Long-form content
authors: ['pubkey1'],
limit: 10
}
],
(events, eventType) => {
if (eventType === 'EVENTS') {
events.forEach(event => {
switch (event.kind) {
case 1:
console.log('Text note:', event.content);
break;
case 6:
console.log('Repost:', event);
break;
case 7:
console.log('Reaction:', event);
break;
case 30023:
console.log('Long-form content:', event);
break;
}
});
} else if (eventType === 'EOSE') {
console.log('End of stored events for author feed');
}
},
{ closeOnEose: false }
);
// Global publish status monitoring
customManager.addPublishCallbackAll((status, eventId) => {
console.log(`Event ${eventId} status:`, status);
});
// Clean up when done
setTimeout(() => {
unsubscribe();
customManager.cleanup();
}, 60000);🏗️ Architecture
NipWorker uses a multi-layered architecture:
- Main Thread: Your application code
- Web Worker: Handles network operations and message routing
- Rust WASM Core: Performs cryptographic operations and message validation
This architecture ensures that heavy operations don't block your main thread, providing a smooth user experience.
📚 API Reference
NostrManager
Factory Function
createNostrManager(config?: NostrManagerConfig): NostrManagerMethods
setSigner(name: string, secretKeyHex: string): void- Set up a signer for publishingsubscribe(subscriptionId: string, requests: Request[], options?: SubscriptionOptions): SharedArrayBuffer- Subscribe to eventspublish(publishId: string, event: NostrEvent, callback?: PublishCallback): void- Publish an eventsignEvent(event: NostrEvent): void- Sign an event without publishinggetPublicKey(): void- Get the public key of the current signerunsubscribe(subscriptionId: string): void- Unsubscribe from eventscleanup(): void- Clean up unused subscriptionsaddPublishCallbackAll(callback: Function): void- Monitor all publish statuses
useSubscription Hook
useSubscription(
subId: string,
requests: Request[],
callback: SubscriptionCallback,
options?: SubscriptionOptions
): () => voidParameters
subId- Unique subscription identifierrequests- Array of Nostr filter objectscallback- Function called when events are receivedoptions- Subscription options (closeOnEose, skipCache, force)
Returns
- Function to unsubscribe and clean up resources
Event Types
EVENTS- New events receivedEOSE- End of stored eventsEOCE- End of cached eventsPUBLISH_STATUS- Status update for published events
🛠️ Development
Prerequisites
- Node.js 18+
- Rust 1.70+
- wasm-pack
Building from Source
# Clone the repository
git clone https://github.com/candypoets/nipworker.git
cd nipworker
# Install dependencies
npm install
# Build WASM modules
npm run build:wasm
# Build the library
npm run buildScripts
npm run dev- Start development servernpm run build- Build for productionnpm run build:wasm- Build WASM modules onlynpm run build:types- Generate TypeScript declarationsnpm run clean- Clean build artifacts
🤝 Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Workflow
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests if applicable
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
🙏 Acknowledgments
- Nostr Protocol - The decentralized social protocol
- nostr-tools - Essential Nostr utilities
- wasm-pack - Rust to WebAssembly workflow
📊 Performance
NipWorker is designed for high performance:
- Fast Event Processing: Rust WASM core processes events up to 10x faster than pure JavaScript
- Non-blocking Operations: Web Worker architecture prevents UI freezing
- Efficient Serialization: MessagePack reduces bandwidth usage by ~30%
- Connection Pooling: Intelligent relay connection management
🔒 Security
- All cryptographic operations are handled by the Rust WASM core
- Private keys never leave the worker thread
- Event validation is performed at the WASM level
- Secure random number generation for key operations
Made with ❤️ by So Tachi
