| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Three conformance fixes surfaced by diffing the live nostr.social output against the 0.0.12 spec: - profile.timestamp -> profile.created_at (nostrcg/did-nostr#117), using the kind-0 created_at (now a defined context term, nostr:created_at). - Emit "modified" (dcterms:modified, ISO-8601) = max(created_at) over the signed parts composed into the document (nostrcg/did-nostr#106). Minimal docs (no signed parts) carry none. - Bound inlined follows to a subset (500) rather than serving the entire list — one live doc was inlining 4760 follows. The complete signed list is the kind-3 event on the relays (nostrcg/did-nostr#104 / #125). diddoc unit tests updated and passing (created_at, modified, bounded follows).
There was a problem hiding this comment.
Updates the DID-document generator to match did:nostr 0.0.12, addressing spec drift found in live output (profile field rename, modified provenance timestamp, and bounded inlined follows).
Changes:
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/diddoc.js | Implements spec-aligned profile.created_at, bounded follows, and modified computed from composed signed parts. |
| test/diddoc.test.js | Updates/extends tests to cover created_at rename, modified behavior, and follows bounding. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| for (const k of ['name', 'about', 'picture', 'website', 'nip05', 'lud16']) if (c[k]) p[k] = c[k]; | ||
| if (c.display_name && !p.name) p.name = c.display_name; | ||
| if (profile.created_at) p.timestamp = profile.created_at; | ||
| if (profile.created_at) p.created_at = profile.created_at; | ||
| if (Object.keys(p).length) doc.profile = p; |
There was a problem hiding this comment.
Good catch — fixed in 7a4fafe. Switched the gate to Number.isFinite(profile.created_at) so a valid created_at of 0 is preserved and the profile field stays consistent with the modified computation.
Sorry, something went wrong.
Address Copilot review on #39: the truthiness gate dropped a valid created_at of 0, while the modified computation uses Number.isFinite. Make them consistent.
| const f = followHexes | ||
| .filter((h) => HEX64.test(String(h).toLowerCase())) | ||
| .map((h) => `did:nostr:${String(h).toLowerCase()}`); | ||
| if (f.length) doc.follows = f; | ||
| if (f.length) doc.follows = f.slice(0, FOLLOWS_LIMIT); |
There was a problem hiding this comment.
Done in 58fc58c — replaced the filter/map-then-slice with a loop that collects up to FOLLOWS_LIMIT valid entries and breaks, so large kind-3 lists aren't fully processed just to be truncated.
Sorry, something went wrong.
Address Copilot review on #39: collect up to FOLLOWS_LIMIT valid entries and stop, instead of validating/mapping the whole kind-3 list before slicing.
| // dcterms:modified serialized as ISO-8601 UTC, no sub-second precision, from a | ||
| // Nostr created_at (Unix seconds). | ||
| const isoFromUnix = (sec) => new Date(sec * 1000).toISOString().replace(/\.\d{3}Z$/, 'Z'); |
There was a problem hiding this comment.
Hardened in 8199af9 — isoFromUnix now returns null for non-safe-integer or out-of-range timestamps (no RangeError in the resolver path), stamps are filtered with Number.isSafeInteger, and modified is only set when a valid ISO value is produced (never modified: null). Added a test for the out-of-range case.
Sorry, something went wrong.
| const stamps = [ | ||
| doc.profile && profile?.created_at, | ||
| doc.follows && follows?.created_at, | ||
| doc.service && relays?.created_at, | ||
| ].filter(Number.isFinite); | ||
| if (stamps.length) doc.modified = isoFromUnix(Math.max(...stamps)); |
There was a problem hiding this comment.
Hardened in 8199af9 — isoFromUnix now returns null for non-safe-integer or out-of-range timestamps (no RangeError in the resolver path), stamps are filtered with Number.isSafeInteger, and modified is only set when a valid ISO value is produced (never modified: null). Added a test for the out-of-range case.
Sorry, something went wrong.
…zation) Address Copilot review on #39: - isoFromUnix returns null for non-safe-integer or out-of-range timestamps instead of throwing RangeError in the public resolver path. - Filter stamps with Number.isSafeInteger (Nostr created_at is integer seconds) and only set modified when isoFromUnix yields a value (never modified: null). - profile.created_at gate also uses Number.isSafeInteger for consistency.
| const stamps = [ | ||
| doc.profile && profile?.created_at, | ||
| doc.follows && follows?.created_at, | ||
| doc.service && relays?.created_at, | ||
| ].filter(Number.isSafeInteger); |
There was a problem hiding this comment.
Good catch, and it surfaced a deeper bug. Fixed in 0aaa789: the kind-0 created_at gate for modified is now (doc.profile || doc.alsoKnownAs), and — the real issue — created_at is only attached to the profile when the kind-0 contributes actual profile fields (previously a bare created_at produced profile: {created_at}). An alsoKnownAs-only kind-0 now yields no profile object but still counts toward modified. Test added.
Sorry, something went wrong.
Address Copilot review on #39: a kind-0 event can contribute alsoKnownAs with no profile fields, so gating the kind-0 created_at on doc.profile alone could understate modified. Gate on (doc.profile || doc.alsoKnownAs).
The created_at was added to the profile object before the non-empty check, so a
kind-0 with only alsoKnownAs produced doc.profile = {created_at}. Attach
created_at only when the kind-0 contributes real profile fields; alsoKnownAs-only
kind-0 now yields no profile but still counts toward modified (prior commit's
gate). Fixes the test added in fcc3382.
DID-document output now conforms to did:nostr 0.0.12 (#39): - profile.timestamp -> profile.created_at (the kind-0 created_at; now a defined context term, nostr:created_at). - Emit "modified" (dcterms:modified, ISO-8601) = max(created_at) over the signed parts actually composed into the document (kind 0 / 3 / 10002). Minimal docs carry none. - Bound inlined follows to a subset (500), short-circuited; the complete signed list is the kind-3 event on the relays (no FollowsEndpoint). - Hardened the public resolver path: corrupt/out-of-range created_at no longer throws (returns no modified), Number.isSafeInteger throughout, and a kind-0 that only contributes alsoKnownAs no longer emits a bare {created_at} profile yet still counts toward modified. Refs: nostrcg/did-nostr 0.0.12 (#106 modified, #117 created_at, #104/#125 follows).
| Back | FazBrowse Home | New Git URL |
Aligns the DID-document generator with the did:nostr 0.0.12 spec. Surfaced by diffing the live nostr.social output against the new spec — three fields had drifted.
Fixes
Tests
test/diddoc.test.js updated and passing: created_at (not timestamp), modified = max over composed parts, and the bounded-follows cap. The rest of the suite is unaffected (the only failures locally are the Mongo-backed db.test.js, which needs a running MongoDB).
Verify against the live drift