Skip to content

Feat: addition of nip-05 verification (issue #261) - #463

Merged
cameri merged 13 commits into
cameri:mainfrom
archief2910:feature/261-NIP-05-verification
Apr 18, 2026
Merged

Feat: addition of nip-05 verification (issue #261)#463
cameri merged 13 commits into
cameri:mainfrom
archief2910:feature/261-NIP-05-verification

Conversation

@archief2910

@archief2910archief2910 commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Description

This PR implements NIP-05 verification as a spam reduction mechanism for nostream, as described in the nostr-rs-relay reference configuration.

Changes included:

NIP-05 Verification Core:

  • Added Nip05Verification and DBNip05Verification types for application and database layers.
  • Added Nip05Settings interface with three operational modes: enabled (require NIP-05 for publishing), passive (validate without blocking), and disabled (no-op).
  • Implemented parseNip05Identifier, extractNip05FromEvent, verifyNip05Identifier, and isDomainAllowed utility functions conforming to the NIP-05 protocol (https://<domain>/.well-known/nostr.json?name=<local>).
  • Created Nip05VerificationRepository following the existing repository pattern with Ramda applySpec DB-to-app mapping.
  • Added Knex migration for the nip05_verifications table with indexes on domain, is_verified, and last_checked_at.

Event Handler Integration:

  • Integrated checkNip05Verification into EventMessageHandler pipeline — blocks unverified authors when mode is enabled, always allows kind-0 (SET_METADATA) events through so users can set their NIP-05 identifier.
  • Implemented processNip05Metadata as fire-and-forget async verification triggered on successful kind-0 event persistence. Deletes verification records when a user removes their NIP-05 from metadata.

Background Re-verification:

  • Added processNip05Reverifications to MaintenanceWorker — periodically re-checks stale verifications respecting verifyUpdateFrequency and maxConsecutiveFailures settings with jittered delays between requests.

Configuration:

  • Added nip05 section to default-settings.yaml with defaults matching nostr-rs-relay: 1 week expiration, 24-hour update frequency, 20 max consecutive failures.
  • Updated CONFIGURATION.md with documentation for all six settings.

Factory Wiring:

  • Threaded Nip05VerificationRepository through workerFactorywebSocketAdapterFactorymessageHandlerFactoryEventMessageHandler and maintenanceWorkerFactoryMaintenanceWorker as a required dependency.

Cleanup:

  • Consolidated duplicate import from '../constants/base' lines in event-message-handler.ts.
  • Removed dead sinonChai import from NIP-05 utility test file.

Related Issue

Closes#261

Motivation and Context

Spam is a persistent problem for public Nostr relays. NIP-05 verification provides a DNS-based identity layer that ties pubkeys to domain names, allowing relay operators to require that event authors have a verifiable internet identity. This is the same approach implemented by nostr-rs-relay and requested in issue #261. The three-mode system (enabled/passive/disabled) gives operators full control over enforcement level without requiring code changes.

How Has This Been Tested?

  • 57 NIP-05 specific unit tests covering:
    • parseNip05Identifier: 12 tests — valid identifiers, subdomains, case normalization, edge cases (null, empty, missing @, no TLD).
    • extractNip05FromEvent: 6 tests — valid kind-0, wrong kind, missing field, bad JSON, empty string, non-string value.
    • isDomainAllowed: 8 tests — whitelist, blacklist, empty lists, case-insensitivity, blacklist-over-whitelist precedence.
    • checkNip05Verification: 12 tests — all three modes, relay pubkey bypass, kind-0 passthrough, missing/expired/unverified records, domain whitelist/blacklist filtering.
    • processNip05Metadata: 10 tests — disabled/passive modes, non-kind-0, delete on missing NIP-05, unparseable identifier, blocked domain, successful/failed verification with upsert assertions, error handling, passive mode verification.
    • processNip05Reverifications: 9 tests — disabled mode, no pending records, success/failure state updates, failure count increment, error resilience across batch, custom config values, undefined fallback defaults, passive mode operation.
  • Updated existing factory tests (message-handler-factory.spec.ts, websocket-adapter-factory.spec.ts) for the new required repository parameter.
  • Full test suite passes: 544 passing (2 pre-existing Windows path-separator failures ).
  • ESLint: 0 errors across all modified files.
  • TypeScript: compiles cleanly with --noEmit.

Screenshots (if appropriate):

N/A

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.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my code changes.
  • All new and existing tests passed.

@archief2910archief2910 changed the title Feature/261-nip-05-verificationFeat: addition of nip-05 verification (#261)Apr 11, 2026
@archief2910archief2910 changed the title Feat: addition of nip-05 verification (#261)Feat: addition of nip-05 verification (issue #261)Apr 11, 2026
@archief2910

Copy link
Copy Markdown
ContributorAuthor

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

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds NIP-05 verification support to nostream to reduce spam by optionally requiring authors to have a verifiable NIP-05 identity, with persistence and periodic re-checking.

Changes:

  • Introduces NIP-05 parsing/extraction/verification utilities plus a DB-backed nip05_verifications repository and migration.
  • Integrates NIP-05 enforcement/metadata-triggered verification into EventMessageHandler and adds periodic re-verification to MaintenanceWorker.
  • Wires the new repository through factories, and documents/configures new nip05.* settings (with unit tests added/updated).

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.

Show a summary per file
FileDescription
test/unit/utils/nip05.spec.tsAdds unit coverage for NIP-05 parsing/extraction/domain filtering utilities.
test/unit/handlers/event-message-handler.spec.tsAdds unit coverage for handler enforcement + metadata-triggered verification behavior.
test/unit/factories/websocket-adapter-factory.spec.tsUpdates factory tests for the new repository dependency.
test/unit/factories/message-handler-factory.spec.tsUpdates factory tests for the new repository dependency.
test/unit/app/maintenance-worker.spec.tsAdds unit coverage for periodic NIP-05 re-verification behavior.
src/utils/nip05.tsImplements NIP-05 identifier parsing, metadata extraction, domain allow/deny logic, and HTTP verification.
src/repositories/nip05-verification-repository.tsAdds repository for storing and querying NIP-05 verification state.
src/handlers/event-message-handler.tsEnforces NIP-05 (mode-dependent) and triggers async verification on kind-0 metadata events.
src/factories/worker-factory.tsInstantiates and injects the NIP-05 verification repository into websocket adapter wiring.
src/factories/websocket-adapter-factory.tsThreads NIP-05 repository into message handler construction.
src/factories/message-handler-factory.tsAdds NIP-05 repository dependency to EventMessageHandler creation.
src/factories/maintenance-worker-factory.tsInstantiates and injects NIP-05 repository into MaintenanceWorker.
src/app/maintenance-worker.tsAdds periodic batch re-verification of stale NIP-05 records.
src/@types/settings.tsIntroduces Nip05Settings and nip05 config field in Settings.
src/@types/repositories.tsAdds INip05VerificationRepository interface.
src/@types/nip05.tsAdds app and DB-layer types for NIP-05 verification records.
resources/default-settings.yamlAdds default nip05 configuration section.
migrations/20260409_120000_create_nip05_verifications_table.jsCreates nip05_verifications table + indexes.
CONFIGURATION.mdDocuments new nip05.* settings.

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

Comment threadsrc/app/maintenance-worker.ts
Comment threadsrc/@types/settings.ts Outdated
Comment on lines +363 to +374
if (!verification || !verification.isVerified) {
return 'blocked: NIP-05 verification required'
}

const expirationMs = nip05Settings.verifyExpiration ?? 604800000
if (verification.lastVerifiedAt) {
const elapsed = Date.now() - verification.lastVerifiedAt.getTime()
if (elapsed > expirationMs) {
return 'blocked: NIP-05 verification expired'
}
}

Comment on lines +367 to +372
const expirationMs = nip05Settings.verifyExpiration ?? 604800000
if (verification.lastVerifiedAt) {
const elapsed = Date.now() - verification.lastVerifiedAt.getTime()
if (elapsed > expirationMs) {
return 'blocked: NIP-05 verification expired'
}
Comment on lines +408 to +423
verifyNip05Identifier(nip05Identifier, event.pubkey)
.then((verified) => {
const now = new Date()
const verification: Nip05Verification = {
pubkey: event.pubkey,
nip05: nip05Identifier,
domain: parsed.domain,
isVerified: verified,
lastVerifiedAt: verified ? now : null,
lastCheckedAt: now,
failureCount: verified ? 0 : 1,
createdAt: now,
updatedAt: now,
}
return this.nip05VerificationRepository.upsert(verification)
})
Comment threadsrc/utils/nip05.ts
Comment on lines +72 to +76
const response = await axios.get(url, {
timeout: VERIFICATION_TIMEOUT_MS,
headers: { 'Accept': 'application/json' },
validateStatus: (status) => status === 200,
})

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@archief2910 good point here, let's set max redirects to 1 (not zero), and limit body and content length. This verification feature can be used to perform DoS attacks or consume the relay's bandwidth for malicious purposes.

Comment threadsrc/utils/nip05.ts Outdated
Comment threadsrc/app/maintenance-worker.ts Outdated
@cameri

Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts in this pull request

@socket-security

socket-securityBot commented Apr 18, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

DiffPackageSupply Chain
Security
VulnerabilityQualityMaintenanceLicense
Addedcross-env@​10.1.010010010082100

View full report

@archief2910

Copy link
Copy Markdown
ContributorAuthor

hey @cameri , i have resolved the conflicts you can check once or should i address the copilot comments too .

Comment threadsrc/utils/nip05.ts Outdated
@archief2910

Copy link
Copy Markdown
ContributorAuthor

hey @cameri , made an issue for migration and resolved the review comments . can you check once .

@cameri
cameri merged commit f7869b0 into cameri:mainApr 18, 2026
9 checks passed
@archief2910
archief2910 deleted the feature/261-NIP-05-verification branch April 18, 2026 14:02
@camericameri mentioned this pull request Apr 22, 2026
Sign up for freeto 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.

NIP-05 verification as a way to reduce spam

3 participants

@archief2910@cameri