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.

Introduction

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.

Core Concepts

Nostr DID Scheme

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.

Relationship with Nostr npubs

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:

Example DID Documents

Minimal DID Document (Offline Resolution)

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.

Enhanced DID Document (With Relay Services)

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.

Complete DID Document (With Profile and Social Graph)

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.

Additional Terminology

The term relay refers to a Nostr relay.

Multikey Verification Method

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:

  1. Start with the x-only public key (32 bytes) from the DID identifier
  2. Construct a 33-byte secp256k1 compressed public key by prepending a parity byte:
    • Use 0x02 for even y-coordinate (standard default)
    • Use 0x03 for odd y-coordinate (when applicable for Nostr keys)
  3. Prepend the multicodec varint for secp256k1 compressed public keys (0xe7, 0x01)
  4. Encode the result using multibase with base16-lower encoding (f prefix)
  5. Place the encoded value in the publicKeyMultibase field

For example, given the x-only public key: 124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2

The transformation steps would be:

  1. Compressed key: 02124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
  2. With multicodec varint: e70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
  3. Multibase base16-lower encoded: 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.

Service Field for Relays

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.

Profile Field (Optional)

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.

Follows Field (Social Graph)

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.

Operations

Create (Register)

Creating a did:nostr identifier involves the following steps:

  1. Generate a secp256k1 key pair using a cryptographically secure random number generator
  2. Extract the public key (32 bytes)
  3. Encode the public key as a 64-character lowercase hexadecimal string
  4. Prefix the encoded public key with "did:nostr:" to form the complete DID

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.

Read (Resolve)

DID resolution for did:nostr identifiers follows this strategy:

  1. HTTP Resolution - Check https://<domain>/.well-known/did/nostr/<pubkey>.json
  2. Offline-first Resolution - Generate minimal DID document from public key alone
  3. Enhanced Resolution - Optionally query Nostr relays for additional metadata

HTTP Resolution

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.

Minimal Resolution

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:

  1. Parse the identifier to extract the 64-character hexadecimal public key
  2. Construct a DID Document with the following required properties:
    • Set the id field to the full DID
    • Set the type field to "DIDNostr"
    • Include a Multikey verification method, transforming the x-only public key following the multicodec/multibase encoding process
    • Set appropriate authentication and assertionMethod references to the verification method

This minimal DID document provides full functionality for cryptographic verification and identity assertion without requiring network connectivity.

Enhanced Resolution with Relay Queries

Optionally, resolvers MAY query known Nostr relays to enhance the DID document with additional metadata and service endpoints.

The enhanced resolution process adds:

  1. Query known Nostr relays for metadata about the public key
  2. Include discovered relay endpoints in the service section of the DID Document
  3. Add any additional metadata found in kind 0 (profile) events
  4. Include social graph information from kind 3 (contact list) events in the follows field

The resolved DID Document will follow the template shown in the "Example DID" section above.

For relay discovery during enhanced resolution, implementations SHOULD:

  1. Check a local cache of known relays for the public key
  2. Query a set of default relays with a filter for kind 0 (metadata) and kind 3 (contact list) events by the target public key
  3. Include discovered relays in the service section of the DID Document
  4. Transform kind 3 contact pubkeys to DIDs and include in the follows field

Note that relay queries and metadata integration are OPTIONAL enhancements to the basic resolution process. Implementations MUST support minimal resolution without network access.

Update (Replace)

This DID Method does not support updating the DID Document.

Delete (Revoke)

This DID Method does not support deactivating the DID Document.

Security & Privacy

Security Considerations

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:

Key Management

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.

Relay Security

Nostr DIDs interact with the Nostr network through relays. These relays may have different security properties and trust models. Implementers SHOULD:

  • Use TLS (wss://) connections to relays to prevent eavesdropping and man-in-the-middle attacks
  • Consider using multiple relays for redundancy and to mitigate denial of service risks
  • Be aware that relays may choose to filter or modify events, potentially affecting DID resolution

Cryptographic Considerations

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.

Privacy Considerations

The did:nostr method has several privacy implications that implementers and users should be aware of:

Identifier Correlation

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:

  • Using different DIDs for different contexts or services
  • Creating purpose-specific DIDs rather than using a single DID for all activities

Public Nature of Nostr

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.

Service Endpoints

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.

Implementations

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.

Resources