nostr-did 0.1.3

Generate W3C-compliant DID Documents from did:nostr identifiers
Documentation

nostr-did

crates.io docs.rs License

Generate W3C-compliant DID Documents from did:nostr identifiers.

Uses nostr-did-key for BIP-340 → Multikey cryptographic transformation and produces fully spec-compliant documents matching the Nostr DID Method Specification v0.0.11.

Quick Start

use nostr_did::DocumentBuilder;

let doc = DocumentBuilder::new()
    .build("did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2")
    .unwrap();

println!("{}", serde_json::to_string_pretty(&doc).unwrap());

Output

§2.3.1 Minimal DID Document (Offline)

Zero network — generated deterministically from the public key alone.

{
  "@context": [
    "https://www.w3.org/ns/cid/v1",
    "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": ["did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1"],
  "assertionMethod": ["did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1"],
  "service": [
    { "id": "...", "type": "Relay", "serviceEndpoint": "wss://nos.lol/" },
    { "id": "...", "type": "Relay", "serviceEndpoint": "wss://relay.damus.io/" },
    { "id": "...", "type": "Relay", "serviceEndpoint": "wss://relay.primal.net/" },
    { "id": "...", "type": "Relay", "serviceEndpoint": "wss://relay.nostr.band/" },
    { "id": "...", "type": "Relay", "serviceEndpoint": "wss://purplepag.es/" }
  ]
}

§2.3.3 Complete DID Document (Profile + Social Graph)

Enriched with Nostr kind 0 profile, kind 3 follows, and alsoKnownAs cross-platform links.

use nostr_did::{DocumentBuilder, Profile};

let profile = Profile {
    name: Some("Alice".into()),
    about: Some("Building the decentralized web".into()),
    picture: Some("https://example.com/alice.jpg".into()),
    nip05: Some("alice@example.com".into()),
    lud16: Some("alice@getalby.com".into()),
    website: Some("https://alice.example.com".into()),
    timestamp: Some(1737906600),
};

let doc = DocumentBuilder::new()
    .with_relays(vec!["wss://relay.damus.io".to_string()])
    .with_profile(profile)
    .with_also_known_as(vec![
        "https://alice.example.com/#me".into(),
        "https://social.example.com/@alice".into(),
        "at://alice.bsky.social".into(),
    ])
    .with_follows(vec![
        "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245".into(),
        "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8".into(),
    ])
    .build("did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2")
    .unwrap();
{
  "@context": [
    "https://www.w3.org/ns/cid/v1",
    "https://w3id.org/nostr/context"
  ],
  "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2",
  "type": "DIDNostr",
  "alsoKnownAs": [
    "https://alice.example.com/#me",
    "https://social.example.com/@alice",
    "at://alice.bsky.social"
  ],
  "verificationMethod": [
    {
      "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1",
      "type": "Multikey",
      "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2",
      "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2"
    }
  ],
  "authentication": ["did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1"],
  "assertionMethod": ["did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1"],
  "service": [
    { "type": "Relay", "serviceEndpoint": "wss://relay.damus.io/" }
  ],
  "profile": {
    "name": "Alice",
    "about": "Building the decentralized web",
    "picture": "https://example.com/alice.jpg",
    "nip05": "alice@example.com",
    "lud16": "alice@getalby.com",
    "website": "https://alice.example.com",
    "timestamp": 1737906600
  },
  "follows": [
    "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
    "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8"
  ]
}

Installation

[dependencies]

nostr-did = "0.1"

API Reference

DocumentBuilder

Method Description
new() Create a builder with 5 default high-availability relays
build(did) Generate the DID Document
with_relay(url) Add a single relay URL
with_relays(vec) Replace all default relays
with_profile(profile) Set Nostr kind 0 profile metadata
with_also_known_as(vec) Set cross-platform identity links
with_follows(vec) Set followed DIDs (kind 3 contacts)

Types

Type Description
DidDocument Full W3C-compliant DID Document
VerificationMethod Multikey verification method
Service Relay or FollowsEndpoint service entry
Profile Nostr kind 0 profile metadata

Default Relays

The builder includes 5 high-availability production relays:

Relay Purpose
wss://nos.lol General purpose, high uptime
wss://relay.damus.io General purpose, Damus ecosystem
wss://relay.primal.net General purpose, Primal ecosystem
wss://relay.nostr.band Full-text search, network trends
wss://purplepag.es Long-form content, user profiles

Running the Demo

cargo run --example demo

License

Dual-licensed under either of:

at your option.