Skip to content

feat: implement NIP-17 & NIP-44 v2 for Modern Direct Messages#458

Open
CKodidela wants to merge 2 commits intocameri:mainfrom
CKodidela:feature/modern-dm-standard
Open

feat: implement NIP-17 & NIP-44 v2 for Modern Direct Messages#458
CKodidela wants to merge 2 commits intocameri:mainfrom
CKodidela:feature/modern-dm-standard

Conversation

@CKodidela
Copy link
Copy Markdown
Contributor

Description

This PR introduces comprehensive support for NIP-17 (Private Direct Messages) and NIP-44 v2 (Encrypted Payloads), establishing the modern standard for secure messaging on Nostr.

Changes included:

  • NIP-17 Support:
    • Added new Event Kinds: Seal (13), Direct Message (14), File Message (15), and Gift Wrap (1059).
    • Implemented GiftWrapEventStrategy to handle and validate incoming Gift Wrap events.
    • Added repository-level protections to block direct relay publication of inner events (Kinds 13, 14, 15), mandating they be encrypted inside a Gift Wrap.
  • NIP-44 v2 Crypto:
    • Implemented nip44Encrypt and nip44Decrypt functions supporting ChaCha20, HKDF extraction/expansion, and MAC verification as per NIP-44 v2 specifications.
    • Added validateNip44Payload to ensure payloads adhere to the exact format requirements without needing to decrypt them.
  • Cleanup:
    • Removed deprecated encryptKind4Event (legacy NIP-04 DM algorithm) from event.ts.
    • Updated package.json to declare NIPs 17 and 44 in supportedNipExtensions.
  • Tests:
    • Added extensive unit tests across NIP-44 encryption logic, Event Strategies, and Message Handlers.
    • Resolved sort-imports ESLint violations in multiple handler specs.

Related Issue

Closes #410

Motivation and Context

The Nostr ecosystem is migrating to NIP-17 and NIP-44 v2 for private direct messages because the legacy NIP-04 standard was found to have systemic metadata leaks and weak encryption. This PR adopts the new, much more private standard by actively supporting Gift Wrap events, handling NIP-44 payload validation natively, and safely rejecting any unprotected inner events before they hit the database, ultimately protecting the relay's users.

How Has This Been Tested?

  • Added specific unit tests for all NIP-44 v2 crypto functions (key derivation, encryption limits, validation failures).
  • Unit tested the newly added helper methods detecting NIP-17 inner events.
  • Covered EventMessageHandler with tests to ensure it correctly blocks standard publications of Kinds 13, 14, and 15 without a wrapper.
  • Validated NIP-59/NIP-17 structural integrity (p tags limitations) within GiftWrapEventStrategy.spec.ts.
  • Automatically passed standard verification layers, including fixing prior ESLint violations in test packages, and successfully executed npm run test:unit.

Screenshots (if appropriate):

Types of changes

  • Non-functional change (docs, style, minor refactor)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly. (Updated supportedNipExtensions in package metadata)
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my code changes.
  • All new and existing tests passed.

This commit introduces comprehensive support for NIP-17 (Private Direct Messages)
and NIP-44 v2 (Encrypted Payloads), establishing the modern standard for
secure messaging on Nostr.

Changes included:
- **NIP-17 Support**:
  - Added new Event Kinds: Seal (13), Direct Message (14), File Message (15), and Gift Wrap (1059).
  - Implemented `GiftWrapEventStrategy` to handle and validate incoming Gift Wrap events.
  - Added repository-level protections to block direct relay publication of inner events (Kinds 13, 14, 15), mandating they be encrypted inside a Gift Wrap.
- **NIP-44 v2 Crypto**:
  - Implemented `nip44Encrypt` and `nip44Decrypt` functions supporting ChaCha20, HKDF extraction/expansion, and MAC verification as per NIP-44 v2 specifications.
  - Added `validateNip44Payload` to ensure payloads adhere to the exact format requirements without needing to decrypt them.
- **Cleanup**:
  - Removed deprecated `encryptKind4Event` (legacy NIP-04 DM algorithm) from `event.ts`.
  - Updated `package.json` to declare NIPs 17 and 44 in `supportedNipExtensions`.
- **Tests**:
  - Added extensive unit tests across NIP-44 encryption logic, Event Strategies, and Message Handlers.
  - Resolved `sort-imports` ESLint violations in multiple handler specs.
@CKodidela
Copy link
Copy Markdown
Contributor Author

@phoenix-server @cameri This pr is ready for review and checks
Local checks including lint, unit passed.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds modern Nostr direct-message support by introducing NIP-17 event kinds and handling for Gift Wrap events, alongside a new NIP-44 v2 encryption/decryption utility and associated unit tests.

Changes:

  • Added NIP-44 v2 crypto utilities (nip44Encrypt, nip44Decrypt, validateNip44Payload, getConversationKey) plus test vectors and round-trip tests.
  • Introduced NIP-17-related event kinds (13/14/15/1059), helpers, and a GiftWrapEventStrategy to validate/persist/broadcast Gift Wrap events.
  • Blocked direct publication of NIP-17 inner kinds (13/14/15) in EventMessageHandler, and updated relay metadata (supportedNips).

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/unit/utils/nip44.spec.ts Adds NIP-44 v2 test vectors, round-trip coverage, and validation tests.
test/unit/utils/event.spec.ts Adds unit tests for new NIP-17 kind helper predicates.
test/unit/handlers/event-strategies/gift-wrap-event-strategy.spec.ts Tests Gift Wrap strategy validation and persistence/broadcast behavior.
test/unit/handlers/event-message-handler.spec.ts Tests blocking of direct publication of kinds 13/14/15.
src/utils/nip44.ts Implements NIP-44 v2 key derivation, encryption/decryption, and payload structural validation.
src/utils/event.ts Removes legacy kind-4 encrypt helper and adds NIP-17 kind helper predicates.
src/handlers/event-strategies/gift-wrap-event-strategy.ts Adds strategy for validating and storing Gift Wrap (1059) events.
src/handlers/event-message-handler.ts Blocks direct publication of NIP-17 inner event kinds (13/14/15).
src/factories/event-strategy-factory.ts Routes kind 1059 events to GiftWrapEventStrategy.
src/constants/base.ts Adds NIP-17 event kinds (13/14/15) and Gift Wrap kind (1059).
package.json Declares support for NIPs 17 and 44 in relay metadata.
package-lock.json Updates lockfile entries (including dependency spec normalization).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- nip44: replace dead try/catch with explicit base64 regex + length%4 check
- gift-wrap: validate recipient p tag is a 64-char lowercase hex pubkey; fix error message
- mirroring worker: block inner event kinds (13/14/15) from being persisted directly
@CKodidela
Copy link
Copy Markdown
Contributor Author

@cameri I've resolved copilot suggestions, This PR is now ready for review
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clarify and explore support for modern DM standards (NIP-17 / NIP-44)

2 participants