nexus-go — Reference
The complete reference for the social layer: the service architecture, the indexer/materializer/enrich model, communities and moderation, and the full bridge.* API surface. For a gentle introduction, start with the Quick guide.
The canonical source of truth for the running services lives in the repository (blurt/nexus-go); this page mirrors it for readers of the manual.
Architecture
nexus-go turns the chain into the social views a front-end needs. blurtd stays the source of truth; nexus-go derives feeds, communities, profiles, and notifications from it into PostgreSQL and serves them read-only.
blurtd block stream
-> nexus-go-indexer (decode chain + custom_json into nexus_* tables)
-> nexus-go-materializer (precompute hot views; rebuildable)
-> nexus-enrich (advance & validate derived datasets)
-> PostgreSQL (canonical nexus_* + materialized views)
-> nexus-go-api (read-only JSON-RPC: bridge.* + social condenser_api.*)
-> front-endsThe four services
- nexus-go-api — the JSON-RPC / bridge API service. It reads the store and serves social methods; it never signs, broadcasts, or holds keys.
- nexus-go-indexer — the chain indexer and sync worker. It tails
blurtd, decodes posts, votes, follows, reblogs, and communitycustom_jsonoperations, and writes them into the canonicalnexus_*tables. - nexus-go-materializer — a derived-view worker that precomputes expensive UI/API views out of the request path.
- nexus-enrich — a post-sync job that advances and validates derived datasets after a baseline restore and catch-up. It is part of the normal path to a correct, current deployment — a data restore alone is not "done".
Data model
The canonical state lives in the nexus_* tables (posts, feeds, reblogs, roles, follows, …), written only by the indexer. Everything else is derived and rebuildable from them without changing chain truth.
The indexer
The indexer is the only writer of canonical state. It tails blurtd and normalizes chain activity into the nexus_* tables — including community moderation operations, which are emitted on-chain as custom_json with id: "community" (see Communities and moderation). Because a full historical index is large, deployments seed from a published data baseline and sync forward rather than indexing from genesis.
The materializer
The materializer builds disposable, rebuildable tables for expensive UI/API views. The canonical source remains the indexed nexus_* tables; materialized tables may be deleted and rebuilt at any time.
Risk controls keep it safe to run:
- base tables stay canonical — the materializer never owns truth;
- each materialized table records
source_head_block,computed_at, andmaterializer_version; - API handlers read the materialized table first and keep a controlled fallback to the canonical query while a view is empty or missing;
- refresh work happens outside the request path;
- a single PostgreSQL advisory lock prevents two materializer processes from refreshing the same views at once.
Current modules:
- Trending tags —
nexus_materialized_trending_tags, derived fromnexus_posts_cache, preservingbridge.get_trending_tags/condenser_api.get_trending_tagsbehavior without a large aggregation on cache misses. - Blog entries —
nexus_materialized_blog_entries, derived fromnexus_feed_cache,nexus_posts, andnexus_reblogs, preserving account blog semantics (top-level posts and reblogs stay in the blog; own posts inside a community stay out unless self-reblogged; undo-reblog removes the row on the next refresh). It keeps the newest entries per account; paging beyond the materialized window falls back to the canonical query.
Accelerator, not authority
The materializer accelerates hot UI paths but never owns historical correctness: any miss falls back to the canonical query. Like the wallet indexer, it is an accelerator over a source of truth that is always reachable.
Communities and moderation
Communities are Blurt accounts (blurt-NNNNNN); their configuration and moderation are broadcast on-chain as custom_json with id: "community", and nexus-go indexes them into nexus_roles and related tables.
Moderation operations nexus-go understands include:
- Post mute —
mutePost/unmutePostmute a single post without muting the author. Stored innexus_posts.is_muted; it does not write tonexus_roles. - Author role —
setRolesets a community role for an account (e.g. a muted author is stored asnexus_roles.role_id = -2).
Effect on the API:
- normal feeds (
bridge.get_ranked_posts,bridge.get_forum_posts) exclude muted posts; - a direct post read still returns the post, but surfaces moderation state in the Bridge
statsobject (e.g."hide": true).
Roles are UX, not a hard wall
Community post-permission types (Topic / Journal / Council) shape what front-ends show, but the backend does not hard-block a non-member's post, and neither does the chain. Treat community roles as a UX convention; any "only authorized authors" guarantee must come from the consuming view, not the community type.
The bridge API surface
Read-only JSON-RPC under the bridge. prefix, grouped by domain. (Method parameters and response shapes are defined by the service; this catalog is the map of what it exposes.)
Feeds and posts
bridge.get_ranked_posts bridge.get_account_posts bridge.get_forum_posts
bridge.get_post bridge.get_post_header bridge.get_discussion
bridge.get_comment_tree_metrics bridge.normalize_postCommunities
bridge.get_community bridge.get_community_context
bridge.list_communities bridge.list_pop_communities bridge.list_top_communities
bridge.list_community_roles bridge.list_community_titles
bridge.list_subscribers bridge.list_all_subscriptionsProfiles and social graph
bridge.get_profile bridge.get_followers bridge.get_following
bridge.get_follow_countNotifications
bridge.account_notifications bridge.post_notifications bridge.unread_notificationsSearch
bridge.search_posts bridge.search_comments
bridge.search_accounts bridge.search_tagsDrafts
bridge.draft_save bridge.draft_list bridge.draft_get bridge.draft_update bridge.draft_deleteMedia
bridge.media_upload_init bridge.media_upload_complete bridge.media_upload_confirm
bridge.media_upload_abort bridge.media_getWitnesses
bridge.get_witness bridge.list_witnesses bridge.get_witness_history
bridge.get_witness_voters bridge.get_account_witness_votes
bridge.get_account_witness_proxyAnalytics and discovery
bridge.get_trending_topics bridge.get_trending_tags bridge.get_top_influencers
bridge.get_top_commenters bridge.get_engagement_metrics bridge.get_reward_analytics
bridge.get_payout_stats bridge.get_historical_statsNFT, referrals, and version
bridge.nft_* bridge.referral_accounts bridge.referral_accounts_count
bridge.get_version bridge.get_nexus_versioncondenser_api compatibility
nexus-go also answers the social subset of condenser_api.* — content and discussion reads (get_content, get_content_replies, the get_discussions_by_* family), account blogs (get_blog, get_blog_entries), and the follow API (get_followers, get_following, get_follow_count). This keeps the classic condenser API backed by the same social store, while consensus methods continue to the node.
Routing through the RPC proxy
Front-ends use a single RPC endpoint. The RPC proxy routes by method prefix: bridge.* and the social condenser_api.* reads go to nexus-go-api; wallet_history.* goes to the wallet indexer; everything consensus goes to the node. From the browser it is one origin and one URL — the fusion happens server-side.
Configuration
nexus-go is configured through environment variables. The runtime essentials:
| Setting | Purpose |
|---|---|
NEXUS_DATABASE_URL | PostgreSQL connection for the services (a Docker-reachable variant is used inside containers). |
BLURT_RPC_URL | blurtd JSON-RPC endpoint the indexer reads from. A dedicated node is preferred for bootstrap and sync. |
NEXUS_API_PORT | Port the API service exposes (fronted by the RPC proxy). |
Materializer toggles (defaults shown):
| Variable | Default | Purpose |
|---|---|---|
NEXUS_MATERIALIZER_ENABLED | true | Master switch for the materializer. |
NEXUS_MATERIALIZER_REFRESH_SEC | 30 | Refresh cadence for materialized views. |
NEXUS_MATERIALIZER_TAGS_ENABLED / NEXUS_MATERIALIZER_TAGS_LIMIT | true / 1000 | Trending-tags module and its cap. |
NEXUS_MATERIALIZER_BLOG_ENABLED / NEXUS_MATERIALIZER_BLOG_REFRESH_SEC / NEXUS_MATERIALIZER_BLOG_LIMIT_PER_ACCOUNT | true / 60 / 200 | Account-blog module, its cadence, and per-account window. |
The full deployment configuration (image selection, data baselines, sync and enrichment orchestration) is operator-specific and documented in the repository; it is intentionally out of scope for this manual.
Deployment
Baseline restore, sync, enrichment, and post-enrichment validation are covered in the repository's deployment docs. This manual keeps the architecture and API surface; the repository keeps the operator procedures.
