Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change NIP-04 direct message and encryption naming to avoid ambiguity with NIP-17 #158

Merged
merged 5 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/NostrSDK/EventCreating.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ enum EventCreatingError: Error {
case invalidInput
}

public protocol EventCreating: DirectMessageEncrypting, NIP44v2Encrypting, RelayURLValidating {}
public protocol EventCreating: LegacyDirectMessageEncrypting, NIP44v2Encrypting, RelayURLValidating {}
88 changes: 45 additions & 43 deletions Sources/NostrSDK/EventKind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ public enum EventKind: RawRepresentable, CaseIterable, Codable, Equatable, Hasha

/// This kind of event should have a recipient pubkey tag.
///
/// See [NIP-04 - Direct Messages](https://github.com/nostr-protocol/nips/blob/master/04.md)
case directMessage
/// See [NIP-04 - Encrypted Direct Message](https://github.com/nostr-protocol/nips/blob/master/04.md)
/// > Warning: Deprecated in favor of [NIP-17 - Private Direct Messages](https://github.com/nostr-protocol/nips/blob/master/17.md).
@available(*, deprecated, message: "Deprecated in favor of NIP-17 - Private Direct Messages.")
case legacyEncryptedDirectMessage

/// This kind of event indicates that the author requests that the events in the included
/// tags should be deleted.
Expand Down Expand Up @@ -127,7 +129,7 @@ public enum EventKind: RawRepresentable, CaseIterable, Codable, Equatable, Hasha
.setMetadata,
.textNote,
.followList,
.directMessage,
.legacyEncryptedDirectMessage,
.deletion,
.repost,
.reaction,
Expand Down Expand Up @@ -156,52 +158,52 @@ public enum EventKind: RawRepresentable, CaseIterable, Codable, Equatable, Hasha

public var rawValue: RawValue {
switch self {
case .setMetadata: return 0
case .textNote: return 1
case .followList: return 3
case .directMessage: return 4
case .deletion: return 5
case .repost: return 6
case .reaction: return 7
case .seal: return 13
case .genericRepost: return 16
case .giftWrap: return 1059
case .report: return 1984
case .muteList: return 10000
case .bookmarksList: return 10003
case .authentication: return 22242
case .longformContent: return 30023
case .dateBasedCalendarEvent: return 31922
case .timeBasedCalendarEvent: return 31923
case .calendar: return 31924
case .calendarEventRSVP: return 31925
case let .unknown(value): return value
case .setMetadata: return 0
case .textNote: return 1
case .followList: return 3
case .legacyEncryptedDirectMessage: return 4
case .deletion: return 5
case .repost: return 6
case .reaction: return 7
case .seal: return 13
case .genericRepost: return 16
case .giftWrap: return 1059
case .report: return 1984
case .muteList: return 10000
case .bookmarksList: return 10003
case .authentication: return 22242
case .longformContent: return 30023
case .dateBasedCalendarEvent: return 31922
case .timeBasedCalendarEvent: return 31923
case .calendar: return 31924
case .calendarEventRSVP: return 31925
case let .unknown(value): return value
}
}

/// The ``NostrEvent`` subclass associated with the kind.
public var classForKind: NostrEvent.Type {
switch self {
case .setMetadata: return SetMetadataEvent.self
case .textNote: return TextNoteEvent.self
case .followList: return FollowListEvent.self
case .directMessage: return DirectMessageEvent.self
case .deletion: return DeletionEvent.self
case .repost: return TextNoteRepostEvent.self
case .reaction: return ReactionEvent.self
case .seal: return SealEvent.self
case .genericRepost: return GenericRepostEvent.self
case .giftWrap: return GiftWrapEvent.self
case .report: return ReportEvent.self
case .muteList: return MuteListEvent.self
case .bookmarksList: return BookmarksListEvent.self
case .authentication: return AuthenticationEvent.self
case .longformContent: return LongformContentEvent.self
case .dateBasedCalendarEvent: return DateBasedCalendarEvent.self
case .timeBasedCalendarEvent: return TimeBasedCalendarEvent.self
case .calendar: return CalendarListEvent.self
case .calendarEventRSVP: return CalendarEventRSVP.self
case .unknown: return NostrEvent.self
case .setMetadata: return SetMetadataEvent.self
case .textNote: return TextNoteEvent.self
case .followList: return FollowListEvent.self
case .legacyEncryptedDirectMessage: return LegacyEncryptedDirectMessageEvent.self
case .deletion: return DeletionEvent.self
case .repost: return TextNoteRepostEvent.self
case .reaction: return ReactionEvent.self
case .seal: return SealEvent.self
case .genericRepost: return GenericRepostEvent.self
case .giftWrap: return GiftWrapEvent.self
case .report: return ReportEvent.self
case .muteList: return MuteListEvent.self
case .bookmarksList: return BookmarksListEvent.self
case .authentication: return AuthenticationEvent.self
case .longformContent: return LongformContentEvent.self
case .dateBasedCalendarEvent: return DateBasedCalendarEvent.self
case .timeBasedCalendarEvent: return TimeBasedCalendarEvent.self
case .calendar: return CalendarListEvent.self
case .calendarEventRSVP: return CalendarEventRSVP.self
case .unknown: return NostrEvent.self
}
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/NostrSDK/Events/BookmarksListEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ public extension EventCreating {
let rawPrivateTags = privateTags.map { $0.raw }
if let unencryptedData = try? JSONSerialization.data(withJSONObject: rawPrivateTags),
let unencryptedContent = String(data: unencryptedData, encoding: .utf8) {
encryptedContent = try encrypt(content: unencryptedContent,
privateKey: keypair.privateKey,
publicKey: keypair.publicKey)
encryptedContent = try legacyEncrypt(content: unencryptedContent,
privateKey: keypair.privateKey,
publicKey: keypair.publicKey)
}
}

Expand Down
60 changes: 0 additions & 60 deletions Sources/NostrSDK/Events/DirectMessageEvent.swift

This file was deleted.

64 changes: 64 additions & 0 deletions Sources/NostrSDK/Events/LegacyEncryptedDirectMessageEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// LegacyEncryptedDirectMessageEvent.swift
//
//
// Created by Joel Klabo on 8/10/23.
//

import Foundation

/// An event that contains an encrypted message.
///
/// > Note: [NIP-04 - Encrypted Direct Message](https://github.com/nostr-protocol/nips/blob/master/04.md)
/// > Warning: Deprecated in favor of [NIP-17 - Private Direct Messages](https://github.com/nostr-protocol/nips/blob/master/17.md).
@available(*, deprecated, message: "Deprecated in favor of NIP-17 - Private Direct Messages.")
public final class LegacyEncryptedDirectMessageEvent: NostrEvent, LegacyDirectMessageEncrypting {

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
}

@available(*, unavailable, message: "This initializer is unavailable for this class.")
override init(kind: EventKind, content: String, tags: [Tag] = [], createdAt: Int64 = Int64(Date.now.timeIntervalSince1970), signedBy keypair: Keypair) throws {
try super.init(kind: kind, content: content, tags: tags, createdAt: createdAt, signedBy: keypair)
}

init(content: String, tags: [Tag] = [], createdAt: Int64 = Int64(Date.now.timeIntervalSince1970), signedBy keypair: Keypair) throws {
try super.init(kind: .legacyEncryptedDirectMessage, content: content, tags: tags, createdAt: createdAt, signedBy: keypair)
}

/// Returns decrypted content from Event given a `privateKey`
public func decryptedContent(using privateKey: PrivateKey) throws -> String {
let recipient = tags.first { tag in
tag.name == TagName.pubkey.rawValue
}

guard let recipientPublicKeyHex = recipient?.value, let recipientPublicKey = PublicKey(hex: recipientPublicKeyHex) else {
throw LegacyDirectMessageEncryptingError.pubkeyInvalid
}

return try legacyDecrypt(encryptedContent: content, privateKey: privateKey, publicKey: recipientPublicKey)
}
}

public extension EventCreating {

/// Creates a ``LegacyEncryptedDirectMessageEvent`` (kind 4) and signs it with the provided ``Keypair``.
/// - Parameters:
/// - content: The content of the text note.
/// - toRecipient: The PublicKey of the recipient.
/// - keypair: The Keypair to sign with.
/// - Returns: The signed ``LegacyEncryptedDirectMessageEvent``.
///
/// See [NIP-04 - Encrypted Direct Message](https://github.com/nostr-protocol/nips/blob/master/04.md)
/// > Warning: Deprecated in favor of [NIP-17 - Private Direct Messages](https://github.com/nostr-protocol/nips/blob/master/17.md).
@available(*, deprecated, message: "Deprecated in favor of NIP-17 - Private Direct Messages.")
func legacyEncryptedDirectMessage(withContent content: String, toRecipient pubkey: PublicKey, signedBy keypair: Keypair) throws -> LegacyEncryptedDirectMessageEvent {
guard let encryptedMessage = try? legacyEncrypt(content: content, privateKey: keypair.privateKey, publicKey: pubkey) else {
throw EventCreatingError.invalidInput
}

let recipientTag = Tag.pubkey(pubkey.hex)
return try LegacyEncryptedDirectMessageEvent(content: encryptedMessage, tags: [recipientTag], signedBy: keypair)
}
}
6 changes: 3 additions & 3 deletions Sources/NostrSDK/Events/MuteListEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ public extension EventCreating {
let rawPrivateTags = privateTags.map { $0.raw }
if let unencryptedData = try? JSONSerialization.data(withJSONObject: rawPrivateTags),
let unencryptedContent = String(data: unencryptedData, encoding: .utf8) {
encryptedContent = try encrypt(content: unencryptedContent,
privateKey: keypair.privateKey,
publicKey: keypair.publicKey)
encryptedContent = try legacyEncrypt(content: unencryptedContent,
privateKey: keypair.privateKey,
publicKey: keypair.publicKey)
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/NostrSDK/Events/Tags/PrivateTagInterpreting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public protocol PrivateTagInterpreting: DirectMessageEncrypting {}
public protocol PrivateTagInterpreting: LegacyDirectMessageEncrypting {}
public extension PrivateTagInterpreting {

/// The private tags encrypted in the content of the event.
Expand All @@ -16,7 +16,7 @@ public extension PrivateTagInterpreting {
/// - Parameter keypair: The keypair to use to decrypt the content.
/// - Returns: The private tags.
func privateTags(from content: String, withName tagName: TagName? = nil, using keypair: Keypair) -> [Tag] {
guard let decryptedContent = try? decrypt(encryptedContent: content, privateKey: keypair.privateKey, publicKey: keypair.publicKey),
guard let decryptedContent = try? legacyDecrypt(encryptedContent: content, privateKey: keypair.privateKey, publicKey: keypair.publicKey),
let jsonData = decryptedContent.data(using: .utf8) else {
return []
}
Expand Down
Loading
Loading