Custom Event Class Registration
NDK provides a registration system that allows you to register custom event classes to work with the wrapEvent() function. This enables you to create your own event types that integrate seamlessly with NDK's event wrapping system.
Overview
The wrapEvent() function automatically wraps raw NDKEvent objects into more specific event types based on their kind property. By default, NDK includes many built-in event classes (like NDKArticle, NDKImage, etc.), but you can also register your own custom event classes.
Registering Custom Event Classes
Requirements
Your custom event class must meet these requirements:
- Extend NDKEvent: Your class should extend the
NDKEventbase class - Static
kindsproperty: An array of event kind numbers this class handles - Static
frommethod: A factory method that creates an instance from anNDKEvent
Example
import { NDKEvent, registerEventClass } from "@nostr-dev-kit/ndk";
class MyCustomEvent extends NDKEvent {
static kinds = [12345]; // Custom event kind number
static from(event: NDKEvent) {
return new MyCustomEvent(event.ndk, event);
}
constructor(ndk: NDK | undefined, rawEvent?: NostrEvent | NDKEvent) {
super(ndk, rawEvent);
this.kind ??= 12345;
}
// Add your custom methods and properties
get customProperty(): string | undefined {
return this.tagValue("custom");
}
set customProperty(value: string | undefined) {
this.removeTag("custom");
if (value) this.tags.push(["custom", value]);
}
}
// Register the class
registerEventClass(MyCustomEvent);Multiple Kinds
Your custom event class can handle multiple event kinds:
class MyMultiKindEvent extends NDKEvent {
static kinds = [12345, 12346, 12347];
static from(event: NDKEvent) {
return new MyMultiKindEvent(event.ndk, event);
}
// Implementation...
}
registerEventClass(MyMultiKindEvent);API Reference
registerEventClass(eventClass)
Registers a custom event class to be used with wrapEvent().
Parameters:
eventClass: An object that implements theNDKEventClassinterface
Example:
registerEventClass(MyCustomEvent);unregisterEventClass(eventClass)
Removes a previously registered event class.
Parameters:
eventClass: The event class to unregister
Example:
unregisterEventClass(MyCustomEvent);getRegisteredEventClasses()
Returns a Set of all currently registered custom event classes.
Returns:
Set<NDKEventClass>: Set of registered event classes
Example:
const registeredClasses = getRegisteredEventClasses();
console.log(`${registeredClasses.size} custom classes registered`);How It Works
When you call wrapEvent() on an NDKEvent, the function:
- Creates a mapping of event kinds to their corresponding classes
- Includes both built-in NDK classes and your registered custom classes
- Looks up the event's
kindin this mapping - If found, calls the class's
from()method to create a wrapped instance - If not found, returns the original
NDKEvent
// This will now return a MyCustomEvent instance for kind 12345
const wrappedEvent = wrapEvent(rawEvent); // rawEvent.kind === 12345Best Practices
- Choose unique kind numbers: Make sure your custom event kinds don't conflict with existing Nostr event kinds
- Follow NIP specifications: If you're implementing a NIP, follow its specifications for event structure
- Extend existing functionality: Build upon NDK's existing event capabilities rather than replacing them
- Handle errors gracefully: Your
from()method should handle invalid or malformed events - Test thoroughly: Test your custom event classes with various input scenarios
Example: Custom Chat Message Event
import { NDKEvent, registerEventClass, NDKKind } from "@nostr-dev-kit/ndk";
class NDKChatMessage extends NDKEvent {
static kinds = [42]; // Using kind 42 for chat messages
static from(event: NDKEvent) {
return new NDKChatMessage(event.ndk, event);
}
constructor(ndk: NDK | undefined, rawEvent?: NostrEvent | NDKEvent) {
super(ndk, rawEvent);
this.kind ??= 42;
}
get roomId(): string | undefined {
return this.tagValue("room");
}
set roomId(roomId: string | undefined) {
this.removeTag("room");
if (roomId) this.tags.push(["room", roomId]);
}
get replyTo(): string | undefined {
return this.tagValue("reply");
}
set replyTo(eventId: string | undefined) {
this.removeTag("reply");
if (eventId) this.tags.push(["reply", eventId]);
}
}
// Register the custom chat message class
registerEventClass(NDKChatMessage);
// Now wrapEvent will automatically create NDKChatMessage instances for kind 42 eventsThis registration system provides a flexible way to extend NDK with your own event types while maintaining compatibility with the existing event wrapping infrastructure.