Keeping expired Nostr events out of a rebuilt local feed

A feed looks correct until a client rebuilds its cache from an older relay export. Events that had already disappeared then show up again. Evaluate expiration at replay time as well as at initial delivery.

Use an absolute deadline in seconds

An expiration tag carries a Unix timestamp encoded as a string. The fixture compares times one second before and after that deadline and prints true, then false. If your clock uses milliseconds, convert it once at the boundary. Comparing raw milliseconds with seconds would make fresh notes disappear immediately.

const tags = [["expiration","1800000000"]];
const deadline = Number(tags.find(([name]) => name === "expiration")[1]);
for (const now of [1799999999, 1800000001]) console.log(now < deadline);

Expire the feed entry even without a new message

A client that stays open can cross the deadline without receiving another event. Check at display time or schedule local eviction, and recheck after resuming from sleep. Treat malformed timestamps according to an explicit parser policy. Expiration controls the view you serve. It cannot retract a note from other people’s screenshots, archives or relays that ignore the optional tag.

github.com NIP-40