Skip to content

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.

text
  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-ends

The 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 community custom_json operations, and writes them into the canonical nexus_* 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, and materializer_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 tagsnexus_materialized_trending_tags, derived from nexus_posts_cache, preserving bridge.get_trending_tags / condenser_api.get_trending_tags behavior without a large aggregation on cache misses.
  • Blog entriesnexus_materialized_blog_entries, derived from nexus_feed_cache, nexus_posts, and nexus_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 mutemutePost / unmutePost mute a single post without muting the author. Stored in nexus_posts.is_muted; it does not write to nexus_roles.
  • Author rolesetRole sets a community role for an account (e.g. a muted author is stored as nexus_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 stats object (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

text
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_post

Communities

text
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_subscriptions

Profiles and social graph

text
bridge.get_profile             bridge.get_followers         bridge.get_following
bridge.get_follow_count

Notifications

text
bridge.account_notifications   bridge.post_notifications    bridge.unread_notifications
text
bridge.search_posts            bridge.search_comments
bridge.search_accounts         bridge.search_tags

Drafts

text
bridge.draft_save   bridge.draft_list   bridge.draft_get   bridge.draft_update   bridge.draft_delete

Media

text
bridge.media_upload_init       bridge.media_upload_complete   bridge.media_upload_confirm
bridge.media_upload_abort      bridge.media_get

Witnesses

text
bridge.get_witness             bridge.list_witnesses        bridge.get_witness_history
bridge.get_witness_voters      bridge.get_account_witness_votes
bridge.get_account_witness_proxy

Analytics and discovery

text
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_stats

NFT, referrals, and version

text
bridge.nft_*                   bridge.referral_accounts     bridge.referral_accounts_count
bridge.get_version             bridge.get_nexus_version

condenser_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:

SettingPurpose
NEXUS_DATABASE_URLPostgreSQL connection for the services (a Docker-reachable variant is used inside containers).
BLURT_RPC_URLblurtd JSON-RPC endpoint the indexer reads from. A dedicated node is preferred for bootstrap and sync.
NEXUS_API_PORTPort the API service exposes (fronted by the RPC proxy).

Materializer toggles (defaults shown):

VariableDefaultPurpose
NEXUS_MATERIALIZER_ENABLEDtrueMaster switch for the materializer.
NEXUS_MATERIALIZER_REFRESH_SEC30Refresh cadence for materialized views.
NEXUS_MATERIALIZER_TAGS_ENABLED / NEXUS_MATERIALIZER_TAGS_LIMITtrue / 1000Trending-tags module and its cap.
NEXUS_MATERIALIZER_BLOG_ENABLED / NEXUS_MATERIALIZER_BLOG_REFRESH_SEC / NEXUS_MATERIALIZER_BLOG_LIMIT_PER_ACCOUNTtrue / 60 / 200Account-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.

Released under the MIT License.