Tag

Tags are one of the main element of Nostr event objects and allow for diverse functionality including referencing public keys p, relays r or even other events e. The format tags take is an array of strings where the first position in the array is reserved for the tag name and the subsequent strings are the values.

The Tag struct and TagKind enum can be used to create and manipulate Tag objects.

Please refer to the Standardized Tags section of the Nostr Protocol NIP repository for an exhaustive list of tags and their related uses within event kinds.

Creating Tags

Rust

TODO

Python

There are multiple methods by which we can create tag objects all of which form part of the Tag class. The simplest of which are the more commonly used single letter tags. In the example below the e, p, a, d, r and t tags are created passing the relevant object/string values to the tag methods event(), public_key(), coordinate(), identifier(), relay_metadata() and hashtag(), respectively.

    print("  Single Letter Tags:")
    # Event ID (hex)
    tag = Tag.event(event.id())
    print(f"     - Event ID (hex)     : {tag.as_vec()}")
    # Public Key (hex)
    tag = Tag.public_key(keys.public_key())
    print(f"     - Public Key (hex)   : {tag.as_vec()}")
    # Coordinate to event
    tag = Tag.coordinate(Coordinate(Kind(0), keys.public_key()))
    print(f"     - Coordinate to event: {tag.as_vec()}")
    # Identifier
    tag = Tag.identifier("This is an identifier value")
    print(f"     - Identifier         : {tag.as_vec()}")
    # Reference/Relay
    tag = Tag.relay_metadata("wss://relay.example.com",RelayMetadata.READ)
    print(f"     - Reference/Relays   : {tag.as_vec()}")
    # Hashtag
    tag = Tag.hashtag("#AskNostr")
    print(f"     - Hashtag            : {tag.as_vec()}")

For the less commonly used but well defined tags the combination of the custom() method is used with an appropriate instance of the TagKind class. Please refer to the documentation for a more comprehensive list of the available options.

    print("  Custom Tags:")
    tag = Tag.custom(TagKind.SUMMARY(), ["This is a summary"])
    print(f"     - Summary    : {tag.as_vec()}")
    tag = Tag.custom(TagKind.AMOUNT(), ["42"])
    print(f"     - Amount     : {tag.as_vec()}")
    tag = Tag.custom(TagKind.TITLE(), ["This is a title"])
    print(f"     - Title      : {tag.as_vec()}")
    tag = Tag.custom(TagKind.SUBJECT(), ["This is a subject"])
    print(f"     - Subject    : {tag.as_vec()}")
    tag = Tag.custom(TagKind.DESCRIPTION(), ["This is a description"])
    print(f"     - Description: {tag.as_vec()}")
    tag = Tag.custom(TagKind.URL(), ["https://example.com"])
    print(f"     - URL        : {tag.as_vec()}")

Finally, if you are looking to parse lists into tag objects the parse() method can be called and passed a list of strings where the first position in the list would represent the tag name and the subsequent strings represent the values.

    print("  Parsing Tags:")
    tag = Tag.parse(["L","Label Namespace"])
    print(f"     - Label Namespace: {tag.as_vec()}")
    tag = Tag.parse(["l","Label Value"])
    print(f"     - Label Value    : {tag.as_vec()}")
JavaScript

TODO

Kotlin

TODO

Swift

TODO

Serializing and Logical Tests

Rust

TODO

Python

Once you have a Tag object, it is relatively straight forward to access the attributes and other related content. The kind() method can be used to access the underlying TagKind object, the single_letter_tag() method returns the SingleLetterTag object and content() method will return the content of the first value position within the tag (position 1 in the array).

The as_standardized() and as_vec() methods will return the tag in both TagStandard (enum) format or as an array of strings, respectively.

    print("  Working with Tags:")
    tag = Tag.public_key(keys.public_key())
    print(f"     - Kind     : {tag.kind()}")
    print(f"     - Letter   : {tag.single_letter_tag()}")
    print(f"     - Content  : {tag.content()}")
    print(f"     - As Std   : {tag.as_standardized()}")
    print(f"     - As Vector: {tag.as_vec()}")

One last point of note is that when processing non-single letter tags it is useful to be able to easily perform tests on these. We can use the kind() method to first surface the TagKind and then call the relevant "is_x" method (e.g. is_title() or is_summary() per the example below) to return a boolean result.

    print("  Logical Tests:")
    tag = Tag.custom(TagKind.SUMMARY(), ["This is a summary"])
    print(f"     - Tag1 (Title?)  : {tag.kind().is_title()}")
    print(f"     - Tag1 (Summary?): {tag.kind().is_summary()}")
JavaScript

TODO

Kotlin

TODO

Swift

TODO