This specification defines a Decentralized Identifier (DID)[[DID-CORE]] method for the Nostr protocol. Nostr is an open-source protocol that utilizes the W3C WebSockets standard.
This document is a draft specification produced by the W3C Nostr Community Group. It is not a W3C Standard nor is it on the W3C Standards Track.
This specification is intended to provide a stable foundation for implementing Nostr-based Decentralized Identifiers. Feedback and contributions are encouraged through the GitHub repository.
This document is a work in progress and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
Decentralized Identifiers (DIDs) are a new type of identifier that enables verifiable, decentralized digital identity. The Nostr DID method connects the emerging W3C DID standard with the Nostr protocol, allowing Nostr keypairs to be used as the foundation for decentralized identifiers.
Nostr is a simple, open protocol that enables a truly censorship-resistant and global social network. By creating a DID method for Nostr, this specification enables Nostr identities to participate in the broader decentralized identity ecosystem, supporting verifiable credentials, authentication, and other identity use cases.
This specification describes how to create, read, and use Nostr DIDs, along with the expected behavior of conforming implementations. The method is designed to be simple, requiring minimal processing overhead while maintaining compatibility with existing Nostr tooling and infrastructure.
The Nostr DID scheme `did:nostr:pubkey` is based on the encoding of a
public key. The public key is represented as a 64-character, lowercase
string. The prefix did:nostr
should be in lowercase, as
per the DID specification.
All DID documents MUST include a type
field with the value "DIDNostr"
to enable proper linked data processing and disambiguation per httpRange-14.
Example Nostr DID:
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
.
In the Nostr ecosystem, public keys are often displayed as "npubs" (e.g., npub1...
),
which are Bech32 encoded versions of the raw public keys for human-friendly display.
It is important to note that Nostr DIDs use the raw 64-character hexadecimal public key, not the npub format. npubs should be considered display-only identifiers to improve readability in user interfaces.
When implementing the DID Nostr method, applications SHOULD accept raw public keys for DID creation. For display in user interfaces, applications MAY choose to show the corresponding npub alongside the DID.
Example mapping:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
npub1cpxejnc58zpcuyh0pt8gvkzpv34qxceu0sqp7jec2nk9nut7p5zs4zyx4c
The following minimal DID document can be generated from the public key alone, without network access:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"] }
This minimal document provides full cryptographic functionality for identity verification and authentication using the standardized Multikey format.
When enhanced through relay queries, additional service endpoints can be included:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"], "service": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#relay1", "type": "Relay", "serviceEndpoint": "wss://some-nostr-relay.org/" } ] }
This enhanced document includes service endpoints discovered through optional relay queries.
A fully enhanced DID document can include profile information and social relationships:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"], "service": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#relay1", "type": "Relay", "serviceEndpoint": "wss://relay.damus.io/" } ], "profile": { "name": "Alice", "about": "Building the decentralized web", "picture": "https://example.com/alice.jpg", "timestamp": 1737906600 }, "follows": [ "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245", "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8" ] }
This complete document enables social applications to resolve identity, profile, relays, and social graph information in a single operation.
For identities with large follow lists, the service array could include a FollowsEndpoint for complete access to thousands of follows without bloating the DID document.
The term relay refers to a Nostr relay.
Nostr DIDs use the Multikey verification method to provide a standardized way to encode secp256k1 public keys for Data Integrity implementations. This method transforms the x-only BIP-340 public key from the DID identifier into a format compatible with W3C Verifiable Credentials Data Integrity specifications.
The transformation process for creating the Multikey representation is as follows:
0x02
for even y-coordinate (standard default)0x03
for odd y-coordinate (when applicable for Nostr keys)0xe7, 0x01
)f
prefix)publicKeyMultibase
field
For example, given the x-only public key:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
The transformation steps would be:
02124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
e70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
Note on Parity Bytes: While most implementations default to the 0x02 prefix for even y-coordinates, Nostr applications may generate keys with either 0x02 or 0x03 prefixes. Implementations should handle both cases when constructing the compressed public key format.
The DID Document SHOULD include a service field to explicitly define relevant relays. This provides a standardized approach for applications resolving a DID document to discover the relays associated with the identity.
Each relay is represented as a service entry with type "Relay" and a
serviceEndpoint that specifies the WebSocket URL of the relay.
Relay URLs at the origin level MUST include a trailing slash (e.g., wss://relay.example.com/
).
Multiple relays can be included in the service array.
DID Documents MAY include a profile
field containing public profile information
that the user has chosen to share. This enables social applications to display profile
information without requiring relay queries.
"profile": { "name": "Alice", "about": "Building the decentralized social web", "picture": "https://example.com/alice.jpg", "nip05": "alice@example.com", "lud16": "alice@getalby.com", "website": "https://alice.example.com", "timestamp": 1737906600 }
The timestamp
field contains the created_at
value from the latest Nostr profile event (Unix seconds),
allowing clients to determine profile freshness and implement intelligent caching strategies.
Note: For Nostr developers: the timestamp
field contains the same value as
event.created_at
from the most recent kind 0 profile event. This allows clients to determine
if their cached profile data is newer or older than what's in the DID document without querying relays.
Note: While DID Core generally recommends against including personally identifiable information, social networking represents a specific use case where users explicitly publish profile information for discovery. This field is optional and should only contain information the user has chosen to make public.
DID Documents MAY include a follows
field containing a list of DIDs that the identity follows,
enabling the construction of decentralized social graphs. This field enhances the DID document with
social relationship information discoverable through standard DID resolution.
"follows": [ "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245", "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8", "did:nostr:82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2" ]
Each entry in the follows array is a DID that represents an identity this DID follows. The follows field is derived from Nostr kind 3 "contact list" events, providing a standardized way to expose social graph relationships through DID resolution.
The follows
field enables applications to:
Note: The follows field mirrors the public contact list already published in Nostr kind 3 events, making this social graph data available through standard DID resolution.
Scalability Consideration: For identities with large follow lists (thousands of follows), implementations SHOULD use a hybrid approach:
"follows": [ "did:nostr:32e182...", // First 100 follows included "did:nostr:46fcbe...", // ... up to 100 entries ], "service": [ { "id": "#follows-api", "type": "FollowsEndpoint", "serviceEndpoint": "https://api.example.com/did/follows/{did}" } ]
This hybrid approach provides immediate access to recent follows while maintaining document size limits and offering complete data access when needed. This pattern addresses the scalability challenge shared with other social protocols like ActivityPub.
This document defines a DID method for Nostr. Implementations MUST conform to the DID Core specification [[DID-CORE]] and the requirements specified in this document.
Creating a did:nostr identifier involves the following steps:
For example, if the generated public key in hex is:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
The corresponding DID would be:
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
Note: No on-chain registration is required as the security and uniqueness are derived from the key generation process.
DID resolution for did:nostr
identifiers follows this strategy:
https://<domain>/.well-known/did/nostr/<pubkey>.json
Servers can host complete DID documents at:
https://example.com/.well-known/did/nostr/<pubkey>.json
Where <pubkey>
is the 64-character lowercase hex public key. The endpoint SHOULD return a complete DID document (minimal or enhanced).
When serving DID documents via HTTP, servers SHOULD include the following headers:
Nostr-Timestamp: 1737906600
Cache-Control: max-age=3600
Last-Modified: Sun, 26 Jan 2025 15:30:00 GMT
The Nostr-Timestamp
header contains the Unix timestamp when the DID document was generated or refreshed. This enables clients to check freshness without parsing the JSON body, allowing for efficient caching strategies.
This enables fast, cacheable resolution without requiring cryptographic computation or relay queries. Servers can serve minimal documents for offline-first scenarios or enhanced documents with service endpoints and profile metadata.
Note: Resolvers MAY check NIP-05 endpoints for a didResolver
field to locate HTTP-hosted DID documents before querying relays.
A conforming resolver MUST be able to generate a valid DID document using only the public key from the DID identifier, without requiring network access to Nostr relays.
The minimal resolution process involves:
id
field to the full DIDtype
field to "DIDNostr"
This minimal DID document provides full functionality for cryptographic verification and identity assertion without requiring network connectivity.
Optionally, resolvers MAY query known Nostr relays to enhance the DID document with additional metadata and service endpoints.
The enhanced resolution process adds:
The resolved DID Document will follow the template shown in the "Example DID" section above.
For relay discovery during enhanced resolution, implementations SHOULD:
Note that relay queries and metadata integration are OPTIONAL enhancements to the basic resolution process. Implementations MUST support minimal resolution without network access.
This DID Method does not support updating the DID Document.
This DID Method does not support deactivating the DID Document.
The security of the did:nostr method relies on the security properties of the underlying Nostr protocol and its public key cryptography. The following security considerations apply:
The private keys corresponding to Nostr DIDs MUST be kept secure. Loss of private keys will result in permanent loss of control over the identifier. Implementers SHOULD employ strong key management practices, including secure key generation, storage, and backup procedures.
Nostr DIDs interact with the Nostr network through relays. These relays may have different security properties and trust models. Implementers SHOULD:
The Nostr DID method uses Schnorr signatures over the secp256k1 curve, which is considered cryptographically secure at the time of writing. However, cryptographic methods may become vulnerable over time. Implementers should stay informed about advancements in cryptanalysis that might affect the security of these signatures.
For additional security requirements, refer to W3C Decentralized Identifiers 8.3.
The did:nostr method has several privacy implications that implementers and users should be aware of:
A Nostr DID directly incorporates a public key that may be used across multiple contexts in the Nostr ecosystem. This creates a potential correlation vector where activities under the same DID can be linked across different services or applications. Users should understand that a single did:nostr identifier does not provide compartmentalization of identity across different contexts.
To mitigate correlation risks, users may consider:
Information associated with a Nostr DID is typically stored on public relays where it can be accessed by anyone. Users should be aware that DID Documents and associated Nostr events are public information. Private or sensitive data should not be included in DID Documents or directly associated with did:nostr identifiers.
The service endpoints (relays) listed in a DID Document may reveal information about a user's network participation and potentially their geographic region or service preferences. Implementers should be cautious about what information might be inferred from service endpoints included in DID Documents.
For additional privacy requirements, refer to W3C Decentralized Identifiers 8.4.
Block, Inc. previously developed a related implementation of the did:nostr method in Rust, but this work has been discontinued and archived. The archived repository can be found at https://github.com/TBD54566975/did-nostr.