Summary
Add support for editing NIP-51 pinned notes from nostter.
Pinned notes are already displayed on profiles and under /<npub>/pins, but nostter does not currently provide an action to update the user's kind 10001 pin list.
Users should be able to pin any kind 1 note to their own profile, including notes authored by other users.
Behavior
Add Pin / Unpin actions to the menu for kind 1 notes.
- Show
Pin when the note is not included in the logged-in user's kind 10001.
- Show
Unpin when it is already included.
- Do not restrict pinning based on the note author.
- Only expose the actions when the current account can write events.
Pinning must update the logged-in user's kind 10001; it must not modify the pinned note or its author.
Pin list format
Store public pins as e tags.
Newly created tags should always include the note author's pubkey.
When a relay hint is known:
["e", "<event id>", "<relay hint>", "<author pubkey>"]
When no relay hint is known:
["e", "<event id>", "", "<author pubkey>"]
Do not guess a relay hint.
Existing shorter forms must continue to be accepted when reading pin lists.
New pins should be appended to the end of the tag list, following NIP-51 ordering.
Updating the pin list
When pinning:
- Use the latest kind
10001 as the base.
- Do not add a duplicate when an
e tag with the same event ID already exists.
- Preserve all unrelated tags.
- Preserve the existing
content.
- Append the new
e tag.
- Sign and publish the updated kind
10001.
When no kind 10001 exists yet, create one with an empty content.
When unpinning:
- Remove all
e tags referencing the target event ID.
- Preserve all other tags.
- Preserve the existing
content.
- If no public pins remain, publish an empty kind
10001 instead of deleting the list event.
Existing content must not be overwritten because NIP-51 may contain private list items there.
State and concurrency
Pin / Unpin operations must not silently overwrite a newer kind 10001 published by another client.
Serialize consecutive Pin / Unpin operations within nostter so that rapid operations do not lose previous changes.
After a successful update, reflect the new state without requiring a page reload in:
- the note menu
- the pinned note on the user's profile
/<npub>/pins
If publishing fails, revert any optimistic local state and report the failure.
Display
Keep the existing behavior where the last e tag is the primary pinned note shown on the profile. As new pins are appended, the most recently pinned note therefore becomes the profile pin.
The pins page should preserve pin-list ordering rather than relay response order. If the newest pin is displayed first, render the list in reverse tag order so its first item matches the profile pin.
A referenced note may no longer be retrievable from available relays. Do not automatically remove such references from kind 10001.
For the logged-in user's own pin list, unavailable references should still be removable.
Out of scope
- Events other than kind
1
- Creating or editing private pinned notes
- Manual reordering
- Writing the deprecated kind
30001 / d = "pin" format
- Automatic migration of deprecated pin lists
References
NIP-51:
https://github.com/nostr-protocol/nips/blob/master/51.md
NIP-01:
https://github.com/nostr-protocol/nips/blob/master/01.md
Existing pinned-notes reader:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/PinnedNotes.ts
Existing profile pinned-note UI:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/components/items/PinnedNote.svelte
Existing pinned-notes page:
https://github.com/SnowCait/nostter/blob/main/web/src/routes/%28app%29/%5Bslug%3Dnpub%5D/pins/%2Bpage.svelte
Existing note menu:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/components/MenuButton.svelte
Summary
Add support for editing NIP-51 pinned notes from nostter.
Pinned notes are already displayed on profiles and under
/<npub>/pins, but nostter does not currently provide an action to update the user's kind10001pin list.Users should be able to pin any kind
1note to their own profile, including notes authored by other users.Behavior
Add Pin / Unpin actions to the menu for kind
1notes.Pinwhen the note is not included in the logged-in user's kind10001.Unpinwhen it is already included.Pinning must update the logged-in user's kind
10001; it must not modify the pinned note or its author.Pin list format
Store public pins as
etags.Newly created tags should always include the note author's pubkey.
When a relay hint is known:
When no relay hint is known:
Do not guess a relay hint.
Existing shorter forms must continue to be accepted when reading pin lists.
New pins should be appended to the end of the tag list, following NIP-51 ordering.
Updating the pin list
When pinning:
10001as the base.etag with the same event ID already exists.content.etag.10001.When no kind
10001exists yet, create one with an emptycontent.When unpinning:
etags referencing the target event ID.content.10001instead of deleting the list event.Existing
contentmust not be overwritten because NIP-51 may contain private list items there.State and concurrency
Pin / Unpin operations must not silently overwrite a newer kind
10001published by another client.Serialize consecutive Pin / Unpin operations within nostter so that rapid operations do not lose previous changes.
After a successful update, reflect the new state without requiring a page reload in:
/<npub>/pinsIf publishing fails, revert any optimistic local state and report the failure.
Display
Keep the existing behavior where the last
etag is the primary pinned note shown on the profile. As new pins are appended, the most recently pinned note therefore becomes the profile pin.The pins page should preserve pin-list ordering rather than relay response order. If the newest pin is displayed first, render the list in reverse tag order so its first item matches the profile pin.
A referenced note may no longer be retrievable from available relays. Do not automatically remove such references from kind
10001.For the logged-in user's own pin list, unavailable references should still be removable.
Out of scope
130001/d = "pin"formatReferences
NIP-51:
https://github.com/nostr-protocol/nips/blob/master/51.md
NIP-01:
https://github.com/nostr-protocol/nips/blob/master/01.md
Existing pinned-notes reader:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/PinnedNotes.ts
Existing profile pinned-note UI:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/components/items/PinnedNote.svelte
Existing pinned-notes page:
https://github.com/SnowCait/nostter/blob/main/web/src/routes/%28app%29/%5Bslug%3Dnpub%5D/pins/%2Bpage.svelte
Existing note menu:
https://github.com/SnowCait/nostter/blob/main/web/src/lib/components/MenuButton.svelte