Skip to content

Commit

Permalink
Add support for NIP-31 alt tags (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyiu authored Oct 20, 2024
1 parent 66012be commit 6063387
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following [NIPs](https://github.com/nostr-protocol/nips) are implemented:
- [ ] [NIP-28: Public Chat](https://github.com/nostr-protocol/nips/blob/master/28.md)
- [ ] [NIP-29: Relay-based Groups](https://github.com/nostr-protocol/nips/blob/master/29.md)
- [x] [NIP-30: Custom Emoji](https://github.com/nostr-protocol/nips/blob/master/30.md)
- [ ] [NIP-31: Dealing with Unknown Events](https://github.com/nostr-protocol/nips/blob/master/31.md)
- [x] [NIP-31: Dealing with Unknown Events](https://github.com/nostr-protocol/nips/blob/master/31.md)
- [ ] [NIP-32: Labeling](https://github.com/nostr-protocol/nips/blob/master/32.md)
- [ ] [NIP-34: `git` stuff](https://github.com/nostr-protocol/nips/blob/master/34.md)
- [ ] [NIP-35: Torrents](https://github.com/nostr-protocol/nips/blob/master/35.md)
Expand Down
16 changes: 16 additions & 0 deletions Sources/NostrSDK/Events/NostrEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ public class NostrEvent: Codable, Equatable, Hashable {
tags.compactMap { EventCoordinates(eventCoordinatesTag: $0) }
}

/// A short human-readable plaintext summary of what the event is about
/// when the event kind is part of a custom protocol and isn't meant to be read as text (like kind:1).
/// See [NIP-31 - Dealing with unknown event kinds](https://github.com/nostr-protocol/nips/blob/master/31.md).
public var alternativeSummary: String? {
firstValueForTagName(.alternativeSummary)
}

/// Unix timestamp at which the message SHOULD be considered expired (by relays and clients) and SHOULD be deleted by relays.
/// See [NIP-40 - Expiration Timestamp](https://github.com/nostr-protocol/nips/blob/master/40.md).
public var expiration: Int64? {
Expand Down Expand Up @@ -375,6 +382,15 @@ public extension NostrEvent {
return self
}

/// Specifies a short human-readable plaintext summary of what the event is about
/// when the event kind is part of a custom protocol and isn't meant to be read as text (like kind:1).
/// See [NIP-31 - Dealing with unknown event kinds](https://github.com/nostr-protocol/nips/blob/master/31.md).
@discardableResult
public final func alternativeSummary(_ alternativeSummary: String) -> Self {
tags.append(Tag(name: .alternativeSummary, value: alternativeSummary))
return self
}

/// Specifies a unix timestamp at which the message SHOULD be considered expired (by relays and clients) and SHOULD be deleted by relays.
/// See [NIP-40 - Expiration Timestamp](https://github.com/nostr-protocol/nips/blob/master/40.md).
@discardableResult
Expand Down
7 changes: 6 additions & 1 deletion Sources/NostrSDK/Tag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import Foundation

/// A constant that describes the type of a ``Tag``.
public enum TagName: String {


/// A short human-readable plaintext summary of what the event is about
/// when the event kind is part of a custom protocol and isn't meant to be read as text (like kind:1).
/// See [NIP-31 - Dealing with unknown event kinds](https://github.com/nostr-protocol/nips/blob/master/31.md).
case alternativeSummary = "alt"

/// a custom emoji that defines the shortcode name and image URL of the image file
case emoji

Expand Down
11 changes: 11 additions & 0 deletions Tests/NostrSDKTests/Events/NostrEventTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ final class NostrEventTests: XCTestCase, FixtureLoading, MetadataCoding {
XCTAssertEqual(metadata.relays?[1], relay2)
}

func testAlternativeSummary() throws {
let alternativeSummary = "Alternative summary to display for clients that do not support this event kind."
let customEvent = try NostrEvent.Builder(kind: EventKind(rawValue: 23456))
.alternativeSummary(alternativeSummary)
.build(signedBy: .test)
XCTAssertEqual(customEvent.alternativeSummary, alternativeSummary)

let decodedCustomEventWithAltTag: NostrEvent = try decodeFixture(filename: "custom_event_alt_tag")
XCTAssertEqual(decodedCustomEventWithAltTag.alternativeSummary, alternativeSummary)
}

func testExpiration() throws {
let futureExpiration = Int64(Date.now.timeIntervalSince1970 + 10000)
let futureExpirationEvent = try NostrEvent.Builder(kind: .textNote)
Expand Down
9 changes: 9 additions & 0 deletions Tests/NostrSDKTests/Fixtures/custom_event_alt_tag.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"content": "",
"created_at": 1687090842,
"id": "b7fbbb4d473db3b3a671ad995f1248d56e9a2ed7f145c1e5f74308e60db2eba7",
"kind": 23456,
"pubkey": "9947f9659dd80c3682402b612f5447e28249997fb3709500c32a585eb0977340",
"sig": "09a1dcace3cec8cd9934b544cede6955c9876e385d73491f1ca5354a0baecda834c43ac9510ef779f8c8c7543b3faccd821e40e0a52dde8527d071cb0d53230c",
"tags": [["alt","Alternative summary to display for clients that do not support this event kind."]]
}

0 comments on commit 6063387

Please sign in to comment.