You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today the "Sign in with Schnorr" button (#403/#405) requires the user to type their username because the IdP login URL has no resource owner to derive the WebID from. As discussed: the cleanest architectural answer is that the local index and the global resolver are the same mechanism, sharded by host. Each JSS pod can serve its own users' DID documents at the did:nostr HTTP-resolution path the spec already defines:
Once a pod publishes its users' DID docs at that path, JSS's existing src/auth/did-nostr.js resolver finds them via the same code path it uses for nostr.social — just one HTTP hop earlier when the pod is the authority for that user. The "type your username" UX hack goes away.
Plan
Server side: add GET /.well-known/did/nostr/:pubkey.json route. For any local account whose profile has a Nostr Multikey VM matching that pubkey (referenced from authentication, with valid controller), generate the DID doc on the fly:
alsoKnownAs: [<webId>] — JSS knows it from the account record
verificationMethod, authentication, assertionMethod per the spec example
Headers per spec: Content-Type: application/did+json, Cache-Control: max-age=3600, Nostr-Timestamp, Last-Modified
404 when no local account claims that pubkey.
Pubkey → account index: small in-memory map, rebuilt on TTL miss (5 min) by scanning the existing _webid_index.json and reading each account's profile/card.jsonld for f-form Multikey or JsonWebKey (kty:EC, crv:secp256k1) entries. Real production wants a PATCH-time hook on the LDP write path; out of scope for this MVP.
Resolver side: tweak resolveDidNostrToWebId to try <request-host>/.well-known/did/nostr/<pubkey>.json BEFORE the configured fallback (nostr.social). For same-pod auth this becomes a zero-network self-resolve.
Today the "Sign in with Schnorr" button (#403/#405) requires the user to type their username because the IdP login URL has no resource owner to derive the WebID from. As discussed: the cleanest architectural answer is that the local index and the global resolver are the same mechanism, sharded by host. Each JSS pod can serve its own users' DID documents at the
did:nostrHTTP-resolution path the spec already defines:https://<pod-host>/.well-known/did/nostr/<pubkey>.json(per did:nostr spec § HTTP Resolution — same path nostr.social and nostr.rocks already implement.)
Once a pod publishes its users' DID docs at that path, JSS's existing
src/auth/did-nostr.jsresolver finds them via the same code path it uses for nostr.social — just one HTTP hop earlier when the pod is the authority for that user. The "type your username" UX hack goes away.Plan
GET /.well-known/did/nostr/:pubkey.jsonroute. For any local account whose profile has a Nostr Multikey VM matching that pubkey (referenced fromauthentication, with valid controller), generate the DID doc on the fly:@context:["https://w3id.org/did", "https://w3id.org/nostr/context"]id:did:nostr:<pubkey>type:"DIDNostr"alsoKnownAs:[<webId>]— JSS knows it from the account recordverificationMethod,authentication,assertionMethodper the spec exampleContent-Type: application/did+json,Cache-Control: max-age=3600,Nostr-Timestamp,Last-Modified_webid_index.jsonand reading each account'sprofile/card.jsonldfor f-form Multikey orJsonWebKey(kty:EC, crv:secp256k1) entries. Real production wants a PATCH-time hook on the LDP write path; out of scope for this MVP.resolveDidNostrToWebIdto try<request-host>/.well-known/did/nostr/<pubkey>.jsonBEFORE the configured fallback (nostr.social). For same-pod auth this becomes a zero-network self-resolve.Acceptance
GET /.well-known/did/nostr/<pubkey>.jsonreturns a CID-shaped DID doc for any account with a matching Nostr Multikey VM in its profileRefs