Kind
As a core component of nostr objects, kinds are used to signal to clients how to parse the data contained within an event.
A kind
is represented by an integer between 0
and 65535
the most well known of which is the Kind 1
,
or text note
which contains plaintext data to be displayed.
Other commonly used kinds include kind 0
(user metadata) and Kind 3
(following/contact lists).
For more details and to see the full range of proposed/adopted Kinds please refer to the Nostr NIPs documentation.
Kind by Integer and Enum
TODO
Working with kinds is facilitated by the Kind
and KindEnum
classes.
If you are familiar already with the specific integer value for a given Kind it is as simple as calling an instance of the class Kind()
and passing the specific number for the Kind you wish to create.
In the example below we've used the common 0
/1
/3
Kinds (user metadata, text note and following list, respectively) as an illustration of this.
Once we've created the Kind
object we can use the as_enum()
method to present the Kind object as an easy to read KindEnum
object.
print(" Kind from integer:")
kind = Kind(1)
print(f" - Kind 1: {kind.as_enum()}")
kind = Kind(0)
print(f" - Kind 0: {kind.as_enum()}")
kind = Kind(3)
print(f" - Kind 3: {kind.as_enum()}")
Alternatively, if you are less familiar with the specific integer values for a Kind we can use the individual Kind classes, in conjunction with the KindEnum
class, to generate the objects.
Below we see the TEXT_NOTE()
, METADATA()
and CONTACT_LIST()
enums being passed to an instance of the Kind
class via the from_enum()
method.
In order to present these as their integer values we can use the as_u16()
method.
print(" Kind from enum:")
kind = Kind.from_enum(cast(KindEnum, KindEnum.TEXT_NOTE()))
print(f" - Kind TEXT_NOTE: {kind.as_u16()}")
kind = Kind.from_enum(cast(KindEnum, KindEnum.METADATA()))
print(f" - Kind METADATA: {kind.as_u16()}")
kind = Kind.from_enum(cast(KindEnum, KindEnum.CONTACT_LIST()))
print(f" - Kind CONTRACT_LIST: {kind.as_u16()}")
Working with kinds is facilitated by the Kind
class.
Unlike the Python bindings there is no enumeration of the kinds, so it helps to be familiar with the specific integer value for a given Kind.
The you call an instance of the class Kind()
and passing the specific number for the Kind you wish to create.
In the example below we've used the common 0
/1
/3
Kinds (user metadata, text note and following list, respectively) as an illustration of this.
Once we've created the Kind
object we can use the toString()
method to present access a string of its integer value.
console.log(" Kind by number:");
let kind = new Kind(1);
console.log(` - Kind 1: ${kind.toString()}`);
kind = new Kind(0);
console.log(` - Kind 0: ${kind.toString()}`);
kind = new Kind(3);
console.log(` - Kind 3: ${kind.toString()}`);
TODO
TODO
TODO
Events and Kinds
TODO
Although it's possible to construct EventBuilder
objects by passing the Kind
class as the first argument (see Event section for examples),
one of the simplest ways of constructing Event
objects is by using the purpose built methods available to the EventBuilder
class.
For example, the text_note()
method can be used to quickly and efficiently create Kind 1 events, the metadata()
and contact_list()
methods can be used in much the same way.
print(" Kind methods EventBuilder:")
event = EventBuilder.text_note("This is a note").sign_with_keys(keys)
print(f" - Kind text_note(): {event.kind().as_u16()} - {event.kind().as_enum()}")
event = EventBuilder.metadata(Metadata()).sign_with_keys(keys)
print(f" - Kind metadata(): {event.kind().as_u16()} - {event.kind().as_enum()}")
event = EventBuilder.contact_list([]).sign_with_keys(keys)
print(f" - Kind contact_list(): {event.kind().as_u16()} - {event.kind().as_enum()}")
Occasionally you may want more generic usage of kinds, like if you wanted to create your own custom (or experimental) event type, or if you want to leverage one of the commonly defined event types (i.e. replaceable, ephemeral, regular, etc.).
kind = Kind(1337)
print(f"Custom Event Kind: {kind.as_u16()} - {kind.as_enum()}")
Although it's possible to construct EventBuilder
objects by passing the Kind
class as the first argument (see Event section for examples),
one of the simplest ways of constructing Event
objects is by using the purpose built methods available to the EventBuilder
class.
For example, the textNote()
method can be used to quickly and efficiently create Kind 1 events, the metadata()
and contactList()
methods can be used in much the same way. In these examples we've used the asU16()
method to present the value of these kinds for logging purposes, this is an alternative way to the integer value from the kind objects.
console.log(" Kind methods EventBuilder:");
let event = EventBuilder.textNote("This is a note").signWithKeys(keys);
console.log(` - Kind textNote(): ${event.kind.asU16()}`);
event = EventBuilder.metadata(new Metadata()).signWithKeys(keys);
console.log(` - Kind metadata(): ${event.kind.asU16()}`);
event = EventBuilder.contactList([]).signWithKeys(keys);
console.log(` - Kind contactList(): ${event.kind.asU16()}`);
TODO
TODO
TODO
Logical Tests
TODO
In addition to the creation and preseentation of kind objects we may also wish to perform logical tests for specific kinds. This can be done for the main categories of kinds as described in the main Nostr protocol documentation.
This test are facilitated by a range of "is_..." method; is_addressable()
, is_ephemeral()
, is_job_request()
, is_job_result()
, is_regular()
and is_replaceable()
.
print(" Kind Logical Tests:")
kind = Kind(30001)
print(f" - Is {kind.as_u16()} addressable?: {kind.is_addressable()}")
kind = Kind(20001)
print(f" - Is {kind.as_u16()} ephemeral?: {kind.is_ephemeral()}")
kind = Kind(5001)
print(f" - Is {kind.as_u16()} job request?: {kind.is_job_request()}")
kind = Kind(6001)
print(f" - Is {kind.as_u16()} job result?: {kind.is_job_result()}")
kind = Kind(1)
print(f" - Is {kind.as_u16()} regular?: {kind.is_regular()}")
kind = Kind(10001)
print(f" - Is {kind.as_u16()} relay replaceable?: {kind.is_replaceable()}")
In addition to the creation and presentation of kind objects we may also wish to perform logical tests for specific kinds. This can be done for the main categories of kinds as described in the main Nostr protocol documentation.
This test are facilitated by a range of "is..." methods; isAddressable()
, isEphemeral()
, isJobRequest()
, isJobResult()
, isRegular()
and isReplaceable()
.
console.log(" Kind Logical Tests:");
kind = new Kind(30001);
console.log(` - Is ${kind.toString()} addressable?: ${kind.isAddressable()}`);
kind = new Kind(20001);
console.log(` - Is ${kind.toString()} ephemeral?: ${kind.isEphemeral()}`);
kind = new Kind(5001);
console.log(` - Is ${kind.toString()} job request?: ${kind.isJobRequest()}`);
kind = new Kind(6001);
console.log(` - Is ${kind.toString()} job result?: ${kind.isJobResult()}`);
kind = new Kind(1);
console.log(` - Is ${kind.toString()} regular?: ${kind.isRegular()}`);
kind = new Kind(10001);
console.log(` - Is ${kind.toString()} replaceable?: ${kind.isReplaceable()}`);
TODO
TODO
TODO