Follow-up to the event class renames: the names around those classes now
match too.
Quartz (published API, every old name kept as a @Deprecated alias/forwarder):
- nip51Lists packages moved: followList -> starterPack, hashtagList -> interestList,
peopleList -> followSet, labeledBookmarkList -> bookmarkSet. The old packages
keep a Deprecated.kt with typealiases and forwarding extension functions
(ReplaceWith points at the new package).
- LnZapPrivateEvent -> PrivateZapEvent, LnZapReceiptValidator -> ZapReceiptValidator,
ChannelListDiff -> PublicChatListDiff, HashtagListDiff -> InterestListDiff.
- Kind 30063 now indexes NIP-82 release notes for search (never NIP-51 content,
which can hold encrypted private items). searchable-events docs updated.
App code (amethyst, commons, desktopApp, cli; no aliases needed):
- model packages nip51Lists.{hashtagLists,peopleList,labeledBookmarkLists,relayFeeds}
-> {interestLists,followSets,bookmarkSets,favoriteRelays}.
- State/cache/UI names derived from the old event names: HashtagListState ->
InterestListState, PeopleListsState -> FollowSetsState, FollowListsState ->
StarterPacksState, LabeledBookmarkList -> BookmarkSet, RelayFeedListState ->
FavoriteRelayListState, ContactCardsState -> UserAssertionsState, NIP90* view
models/renderers -> Dvm*, LnZap* handlers -> Zap*, SealedRumor* -> Seal*, and
Account.peopleLists/followLists/hashtagList -> followSets/starterPacks/interestList.
- String literals were left untouched, so preference keys and @SerialName values
stored on disk are unchanged.
- The generic PeopleList UI model (shared by follow sets and starter packs) and the
EmojiPackSelection route (which shows a kind 30030 pack) keep their names.
Docs: plans, brainstorms, changelogs, skills and READMEs use the new names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015VvJ8XpeYqBe8bYT3bJ7UD
5.6 KiB
Account State-Object Catalog
Account.kt composes ~50 feature state objects (not raw StateFlow
properties). Each object pins its backing addressable note in LocalCache,
exposes val flow: StateFlow<…> (decrypted + backup-merged + stateIn), and
offers suspend mutation helpers that return signed events. Consumers read
account.<property>.flow.
(Property and class names are exact as of the current Account.kt; if one has
been renamed, grep Account.kt for the class name.)
Identity & Contacts
| Account property | State class | Kind | Package |
|---|---|---|---|
userMetadata |
UserMetadataState |
0 | amethyst/.../model/nip01UserMetadata/ |
kind3FollowList |
Kind3FollowListState |
3 | model/nip02FollowLists/ |
muteList (+ muteListDecryptionCache) |
MuteListState |
10000 | model/nip51Lists/muteList/ |
blockPeopleList, peopleLists |
BlockPeopleListState, FollowSetsState |
NIP-51 people sets | model/nip51Lists/followSets/ |
followLists |
StarterPacksState |
NIP-51 follow sets | model/nip51Lists/followSets/ |
hiddenUsers |
HiddenUsersState — derived from muteList.flow + blockPeopleList.flow |
— | model/nip51Lists/ |
allFollows |
MergedFollowListsState — merges kind3 + people/follow/hashtag/geohash/community lists |
— | model/serverList/ |
Relay Lists
| Account property | State class | Kind | Package |
|---|---|---|---|
nip65RelayList |
Nip65RelayListState |
10002 | model/nip65RelayList/ |
dmRelayList |
DmRelayListState |
10050 | model/nip17Dms/ |
searchRelayList |
SearchRelayListState |
10007 | model/nip51Lists/searchRelays/ |
blockedRelayList |
BlockedRelayListState |
10006 | model/nip51Lists/blockedRelays/ |
localRelayList |
LocalRelayListState |
local | model/localRelays/ |
privateStorageRelayList |
PrivateStorageRelayListState |
private storage | model/edits/ |
keyPackageRelayList, trustedRelayList, proxyRelayList, broadcastRelayList, indexerRelayList, favoriteRelayList |
per-feature …RelayListState classes, each with a DecryptionCache sibling |
custom relay sets | model/nip51Lists/… |
Derived relay views (merge several of the above): homeRelays
(AccountHomeRelayState), outboxRelays, dmRelays, notificationRelays,
trustedRelays, followPlusAllMineWithIndex, followPlusAllMineWithSearch,
defaultGlobalRelays.
Content Lists
| Account property | State class | Kind | Package |
|---|---|---|---|
bookmarkState (and legacy oldBookmarkState) |
BookmarkListState |
10003 | model/nip51Lists/ |
bookmarkSets |
BookmarkSetsState |
NIP-51 bookmark sets | model/nip51Lists/bookmarkSets/ |
pinState |
PinListState |
NIP-51 | model/nip51Lists/ |
interestSets |
InterestSetsState |
NIP-51 interest sets | model/nip51Lists/interestSets/ |
hashtagList / geohashList |
InterestListState / GeohashListState |
NIP-51 | model/nip51Lists/interestLists/, …/geohashLists/ |
communityList |
CommunityListState |
NIP-72 communities | model/nip72Communities/ |
favoriteAlgoFeedsList |
FavoriteAlgoFeedsListState |
NIP-51 | model/nip51Lists/ |
emoji, ownedEmojiPacks |
EmojiPackState, OwnedEmojiPacksState |
10030 | commons/.../commons/model/nip30CustomEmojis/ |
publicChatList |
PublicChatListState |
NIP-28 | commons/.../commons/model/nip28PublicChats/ |
ephemeralChatList |
EphemeralChatListState |
ephemeral chats | commons/.../commons/model/emphChat/ |
blossomServers |
BlossomServerListState |
Blossom (BUD) | model/nipB7Blossom/ |
Other Feature State
| Account property | State class | Purpose | Package |
|---|---|---|---|
vanish |
VanishRequestsState |
NIP-62 vanish requests | model/nip62Vanish/ |
appSpecific |
AppSpecificState |
NIP-78 app data | model/nip78AppSpecific/ |
otsState |
OtsState |
NIP-03 OpenTimestamps | model/nip03Timestamp/ |
live*FollowListsPerRelay |
OutboxLoaderState(...).flow — already a flow |
per-feed outbox routing | model/topNavFeeds/ |
privateDMDecryptionCache, draftsDecryptionCache |
PrivateDMCache, DraftEventCache |
NIP-44 decryption caches | — |
Note the migration direction: newer/extracted state classes live in
commons/src/commonMain/.../commons/model/, the rest still in
amethyst/src/main/java/.../model/. Check both when looking for one.
Publishing Mutations
State objects' mutation helpers (e.g. MuteListState.hideUser(pubkey),
BookmarkListState add/remove) build and sign the updated replaceable
event via the quartz event class (XEvent.add / remove / create) and return
it. The caller (usually a method on Account) is responsible for sending it
through the client. Decryption results are cached in the paired
…DecryptionCache so re-renders don't re-decrypt.
When a State Object Doesn't Exist Yet
If you're adding a new NIP that's user-scoped, follow the pattern (full recipe
in SKILL.md):
- Create
model/nipXX…/XState.ktmodeled onMuteListState(encrypted) orBookmarkListState(plain). - Pin the note with
cache.getOrCreateAddressableNote(...), exposeval flow: StateFlow<…>viastateIn(scope, Eagerly, default). - Instantiate it in
Account.kt(plus aDecryptionCachesibling if private), and wire the relay subscription (seerelay-clientskill). - Add mutation helpers that build, sign, and return the event; publish from the calling site.
- Use
AccountSettingsfor the local backup copy if the list must survive relay loss.