nostr-did

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/did/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/did/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.