Repository navigation
feat: viewer_fid viewer_context and thread_hash on v2 casts - #43
Merged
CassOnMars merged 1 commit intoOct 30, 2026
Merged
Conversation
With `viewer_fid`, the cast endpoints fill Neynar's `viewer_context` on each cast (liked, recasted) and on its author and mentioned profiles (following, followed_by, blocking, blocked_by), using point lookups in the reaction and link stores. Without it the response has no viewer_context, as before. Every cast now carries `thread_hash`: its own hash for a top-level cast, else the root found by walking parent cast ids in the cast store (at most 64 hops), omitted when an ancestor is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
backmeupplz
added a commit
to backmeupplz/quilcast
that referenced
this pull request
Oct 22, 2026
…f reach - A thread that starts with the gap gets a ⋯ bubble in the avatar column and room above, so it reads as the top of that thread instead of the end of the post above; a gap in the middle has more room too. - A reply to a parent already shown above is left out, so one conversation doesn't show twice in a row. - Ready for Hypersnap PR #43 (farcasterorg/hypersnap#43): the parent is fetched with viewer_fid, its author's viewer_context.following skips the follow lookup, and thread_hash fetches the root directly; until haatz runs it, the old lookups are used (now at most 2 steps above the parent). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
martinvr
approved these changes
Oct 29, 2026
CassOnMars
approved these changes
Oct 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fields Neynar returns on cast objects that the v2 API leaves empty today. A client building reply threads needs both: whether the viewer follows each author and already liked or recast each cast, and which conversation a reply belongs to. Without them it makes extra requests for every cast on the page.
viewer_fidviewer_fidwas already parsed indispatchbut never used. It now works on:/v2/farcaster/feed/following,/v2/farcaster/feed(following and trending),/v2/farcaster/feed/trendingand its aliasesfor_youandtopic/v2/farcaster/feed/channels,/v2/farcaster/feed/parent_urls/v2/farcaster/feed/user/casts/v2/farcaster/cast,/v2/farcaster/cast/bulk,/v2/farcaster/casts/v2/farcaster/cast/conversation(every cast in the tree)With it, each cast gets
viewer_context: {"liked": bool, "recasted": bool}. The author and each mentioned profile getviewer_context: {"following": bool, "followed_by": bool, "blocking": bool, "blocked_by": bool}. These are theCastViewerContextandViewerContexttypes already intypes.rs.blocking/blocked_bycome fromblocklinks, the same links/v2/farcaster/block/listreads.Each value is one point lookup (
ReactionStore::get_reaction_add,LinkStore::get_link_add), behind two newHubQueryHandlermethods,has_reactionandhas_link. That is 2 lookups per cast and 4 per user. Withoutviewer_fidnothing is looked up andviewer_contextis left out, as before.thread_hashthread_hashis always on, set inmessage_to_cast, so every endpoint that returns casts has it:parent_cast_idthroughget_cast_by_hashwith the parent's FID. That is one direct cast store read per level, so a depth-d reply costs d reads;MAX_THREAD_HOPS), the field is left out, as it is today.There is no cache. Ancestors don't change, so one could be added later if conversation endpoints show the cost.
Tests
test_thread_hash_walks_to_the_root: a root, a reply and a reply to the reply all get the root's hash. A missing ancestor gives none. A self-parented cast stops at the hop limit.test_viewer_context_only_with_viewer_fid:/castwithviewer_fidreturns the cast's and users'viewer_contextfrom the viewer's likes, follows and blocks. Withoutviewer_fidthere is noviewer_contexton the cast, the author or mentioned profiles.test_has_link_and_has_reaction(server_tests): the real store lookups across two shards. A follow and a like are found. A reverse follow, a block and a removed recast are not.cargo test --lib: everything passes except 4 storage tests (test_storage_slot_from_rent_event,test_storage_slot_with_mix_of_units,test_user_with_low_total_storage_cannot_lend,test_commit_username_proof_messages). Those fail the same way on currentmain.cargo fmt --all --checkis clean, and clippy reports nothing in the new code. I haven't run it on a synced node.