Skip to content

NIP-134: define DNS record set format in event content#7

Merged
melvincarvalho merged 4 commits into
gh-pagesfrom
nip-134-dns-records
Jul 8, 2026
Merged

NIP-134: define DNS record set format in event content#7
melvincarvalho merged 4 commits into
gh-pagesfrom
nip-134-dns-records

Conversation

@melvincarvalho

Copy link
Copy Markdown
Contributor

Closes #2

Extends NIP-134 so the content field of a kind 31034 event carries a full DNS record set, making the event a complete signed zone for <pubkey>.nostr — the PKARR SignedPacket idea, but signatures come free with Nostr events.

Format

JSON object with a records array; each record is [type, name, ttl, data]:

  • typeA, AAAA, CNAME, TXT, SRV MUST be supported; unknown types MUST be ignored (extensible)
  • name — relative to the <pubkey>.nostr zone, @ for apex
  • ttl — seconds; resolvers MAY cap
  • data — DNS presentation format, as in a zone file

Semantics

  • Kind 31034 is parameterized replaceable, so relays keep only the newest event per pubkey/d — latest created_at wins, mirroring PKARR's BEP44 sequence numbers
  • Empty or unparseable content = empty record set; the u tag mapping is unaffected, so existing events remain valid
  • Caching per record TTL, optional staleness policy on created_at

This unblocks the DNS/DoH bridge (#3) and dual-stack pkarr publishing (#4).

Specifies a JSON record set for the content field of kind 31034
events, turning an event into a complete signed zone for
<pubkey>.nostr:

- Records as [type, name, ttl, data] arrays with data in DNS
  presentation format
- MUST support A, AAAA, CNAME, TXT, SRV; unknown types ignored
- Latest created_at wins via the parameterized replaceable range,
  mirroring PKARR's BEP44 sequence numbers
- Freshness and caching guidance for resolvers

Copilot AI 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

This PR extends the DNSTR/NIP-134 documentation to define a concrete on-wire format for carrying a full DNS record set inside kind 31034 event content, enabling events to represent complete signed zones for <pubkey>.nostr.

Changes:

  • Updates the kind 31034 content description to allow either empty content or a DNS record set.
  • Adds a new “DNS record set” section specifying a JSON encoding, required record types, and caching/conflict-resolution semantics.
  • Provides an example event showing how a record set is embedded in the content string.

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

Comment thread README.md Outdated
@@ -46,6 +46,45 @@ Example event:

Services and tools that wish to make use of this NIP SHOULD first verify the authenticity of the event by checking the signature and then map the domain name specified in the content to `npub.nostr` or `pubkey.nostr`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in ceb5dca — now says the domain mapping comes from the u tag.

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated

## Implementation

In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and use the field in the content as the domain. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in ceb5dca — the implementation section now points at the u tag for the domain and treats content as the record set.

- Domain mapping comes from the u tag, not content; fix the two
  sentences that still said otherwise
- TTL is a non-negative integer
- Quote the TXT RDATA in the example per DNS presentation format

Copilot AI 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

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

Comment thread README.md Outdated
```

Services and tools that wish to make use of this NIP SHOULD first verify the authenticity of the event by checking the signature and then map the domain name specified in the content to `npub.nostr` or `pubkey.nostr`.
Services and tools that wish to make use of this NIP SHOULD first verify the authenticity of the event by checking the signature and then map the domain name specified in the `u` tag to `npub.nostr` or `pubkey.nostr`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 401f31b — reworded so the .nostr name resolves to the u tag domain.

Comment thread README.md Outdated
## Implementation

In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and use the field in the content as the domain. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.
In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and use the `u` tag as the domain, treating the `content` (if present) as the DNS record set. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 401f31b — lookup guidance now says to filter on the d tag (empty string).

Comment thread README.md Outdated

Kind `31034` falls in the parameterized replaceable range, so relays retain only the newest event per `pubkey` and `d` tag. The record set with the highest `created_at` wins, serving the same role as PKARR's BEP44 sequence numbers.

Resolvers SHOULD cache verified record sets for the record TTL, and MAY apply a freshness policy that treats record sets as stale when `created_at` is older than a policy-defined age, prompting a re-query of relays.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 401f31b — caching now honours each record's own ttl (optionally capped) rather than one TTL for the whole set.

- Fix mapping direction: .nostr name resolves to the u tag domain
- Lookup queries filter on d tag (empty string)
- Caching honours each record's own ttl, not one TTL for the set

Copilot AI 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

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

Comment thread README.md Outdated
Comment thread README.md Outdated

### Freshness and conflict resolution

Kind `31034` falls in the parameterized replaceable range, so relays retain only the newest event per `pubkey` and `d` tag. The record set with the highest `created_at` wins, serving the same role as PKARR's BEP44 sequence numbers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 48b5446 — replaceable semantics are now SHOULD-level for relays, with an explicit client rule to select the highest created_at.

Comment thread README.md
## Implementation

In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and use the field in the content as the domain. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.
In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and the `d` tag set to the empty string, then use the `u` tag as the domain, treating the `content` (if present) as the DNS record set. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 48b5446 — the Use Case section now verifies the u tag, with content as the optional record set.

- Use <npub>.nostr / <pubkey>.nostr placeholders so they don't read
  as literal hostnames
- State replaceable semantics at SHOULD level with an explicit
  client selection rule
- Fix the Use Case section to verify the u tag, not content

Copilot AI 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

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

Comment thread README.md

The `content` field MAY contain a DNS record set, making the event a complete signed zone for `<pubkey>.nostr` (or `<npub>.nostr`). Because Nostr events are signed, this gives signed record sets in the manner of PKARR's `SignedPacket` without any additional machinery.

The record set is encoded as a JSON object with a `records` array. Each record is an array of four elements:
Comment thread README.md
}
```

A `content` that is empty or does not parse as a JSON object with a `records` array MUST be treated as an empty record set; the `u` tag mapping continues to apply regardless.
Comment thread README.md
## Implementation

In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and use the field in the content as the domain. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.
In order to lookup a .nostr domain you simply query the pubkey with kind=31034 and the `d` tag set to the empty string, then use the `u` tag as the domain, treating the `content` (if present) as the DNS record set. Some lookup services may choose to fallback to profile web page or nip-05 origin, as desired.
@melvincarvalho
melvincarvalho merged commit 2c1fdf3 into gh-pages Jul 8, 2026
1 check passed
@melvincarvalho
melvincarvalho deleted the nip-134-dns-records branch July 8, 2026 08:32
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.

Extend NIP-134: define a DNS record format in event content

2 participants