Frontend Integrations

Add Curyo to an existing app with the SDK, then register a frontend operator if you want votes from your interface to accrue frontend fees.

Two Tracks

Most teams should think about integration in two layers. First, make the product work well in your app. Second, decide whether you also want to operate a registered frontend address and participate in the protocol's frontend-fee model.

Use the SDK

Use @curyo/sdk when you want hosted reads, vote helpers, and frontend attribution support in an existing website or app.

Open SDK docs

Register an Operator

Register a frontend address when you want votes made through your interface to earn 4% of the remaining 95% from settled two-sided rounds.

Open frontend settings

Start With the SDK

The SDK is the fastest path for integrating Curyo into an existing codebase. It packages the hosted read client and the vote/frontend helpers that the reference app already relies on.

If you want implementation details, start with the SDK package and the reference frontend.

  • Use it to fetch indexed content, profiles, rounds, votes, stats, categories, and frontend records.
  • Use it to build vote commit payloads and transfer calldata without copying protocol plumbing into your app.
  • Use frontendCode or defaultFrontendCode when your deployment should attribute votes to a registered frontend operator.

The full implementation guide lives on the SDK page.

Register a Frontend Operator

Frontend operators who build frontends, mobile apps, or integrations receive 4% of the remaining 95% from settled two-sided rounds on votes made through their interface. Bounties also reserve a default 3% share for the eligible frontend operator attributed at vote commit time.

The reference app registration flow lives in Settings.

  1. Stake 1,000 HREP to the FrontendRegistry contract.
  2. Integrate: Include your registered address in the vote payload, or configure it as the default frontend code in the SDK.
  3. Claim: First call RoundRewardDistributor.claimFrontendFee(contentId, roundId, frontend) from your operator address on each settled round, then withdraw your accumulated HREP from FrontendRegistry.claimFees() while active, or with completeDeregister() after exit. If governance slashes your frontend, you must restore the full 1,000 HREP bond before fee claims can accrue to you again. Reward-pool frontend shares are paid automatically when eligible voters claim.

Frontend Attribution

Include your frontend address in the payload you send through the single-transaction vote flow:

HumanReputation.transferAndCall(
    votingEngineAddress,
    stakeAmount,
    abi.encode(
        contentId,
        roundReferenceRatingBps,
        commitHash,
        ciphertext,
        frontend, // Your registered frontend address
        targetRound,
        drandChainHash
    )
)

If you are using the SDK or the reference app, set NEXT_PUBLIC_FRONTEND_CODE to your operator address and the vote helpers will include it automatically.

Operator Responsibilities

Registering a frontend operator is more than adding one address to calldata. If you want to run a serious production integration, you should treat fee attribution, round resolution, indexed reads, and moderation as part of the operator surface.

Run a Resolution Service

Every frontend operator should also run a resolution service, a background service that keeps the protocol moving. It performs three critical tasks:

  1. Revealing votes: After each 20-minute epoch ends, the service decrypts tlock ciphertexts using the drand randomness beacon and calls revealVoteByCommitKey(contentId, roundId, commitKey, isUp, salt) for each unrevealed commit. Votes stay hidden until this step runs.
  2. Settling rounds: Once at least 3 votes are revealed and all past-epoch votes have been revealed (or the 60-minute reveal grace period has expired), the service calls settleRound(contentId, roundId) to finalize the round, update the content rating, and open rewards for claiming.
  3. Finalizing and cleanup: If commit quorum was reached but reveal quorum never materializes by the final grace deadline, the service can call finalizeRevealFailedRound(contentId, roundId). After terminal states, it should also batch processUnrevealedVotes(contentId, roundId, startIndex, count) so unrevealed stakes are swept or refunded.

Without resolution services, votes would never be revealed and rounds would never resolve. Running one alongside your frontend ensures a smooth experience for your users and contributes to the health of the network. Since these actions are permissionless, anyone can run a resolution service. Under the keeper-assisted/self-reveal model, reveal still relies on off-chain drand decryption and stanza validation rather than an on-chain proof that the stored ciphertext was honestly decryptable, so the keeper is a trust-minimized convenience layer rather than a cryptographic gatekeeper. The more independent services running, the more resilient the network becomes.

The reference resolution runtime lives in packages/keeper.

Run an Indexer or Back-End

For the best user experience, frontend operators should run their own indexer and/or back-end service. Reading blockchain data directly from an RPC node for every page load is slow and expensive. An indexer listens to contract events and stores the data in a database so your frontend can query it instantly.

  • Faster load times: Pre-indexed data means your UI doesn't wait for RPC calls to return historical state.
  • Lower RPC costs: Batch-synced data reduces the number of calls to your RPC provider.
  • Richer queries: An indexed database lets you filter, sort, and aggregate data in ways that direct blockchain reads alone cannot support efficiently.

The reference implementation uses Ponder as its indexer. You are free to use any indexing stack (Ponder, The Graph, custom solutions) as long as your frontend can serve data quickly and reliably.

The current indexing service code lives in packages/ponder.

Own Your Moderation Layer

Frontend operators are allowed and encouraged to implement their own frontend moderation layer to comply with local regulations and their own platform policies. Because Curyo is a decentralized protocol, there is no protocol-level censorship, and content submitted to the blockchain is permanent. However, each frontend is free to decide what it displays to its users.

The reference implementation includes a policy-driven moderation layer that:

  • Blocks submissions containing prohibited terms or blocked domains in URLs, questions, descriptions, seeded category names, category tags, or unsafe media embeds.
  • Filters indexed reads centrally in the bundled Ponder query layer so blocked content stays hidden across feed loads, discovery modules, category reads, and direct requested-content lookups.
  • Notifies users with inline validation and clear warning messages when their input is rejected or a requested item is hidden.

Frontend operators can customize and extend their moderation approach in several ways:

  • Keyword filtering - Expand or adjust the built-in blocklist of prohibited terms for URLs and text.
  • Domain blocklists - Maintain a list of domains that should never be displayed or submitted.
  • Third-party moderation APIs - Integrate services like content safety classifiers for more sophisticated filtering.
  • Manual review workflows - Implement flagging and human review for edge cases.

Each frontend operator is responsible for the content they serve to their audience. In the reference implementation, moderation is enforced in frontend submit validation plus the bundled Ponder query layer; it has no effect on the underlying protocol or on other frontends that choose a different policy.

The reference policy list lives in packages/node-utils/src/contentModeration.ts, the lower-level matching helpers live in packages/nextjs/utils/contentFilter.ts, the Ponder query-layer enforcement lives in packages/ponder/src/api/moderation.ts, and the submit-form validators live in packages/nextjs/lib/moderation/submissionValidation.ts.

Governance Oversight

Frontend operators are subject to governance control:

  • Slashing - Governance can slash staked HREP for abuse and confiscate already accrued frontend fees.
  • Rebonding required - After a partial slash, operators must top back up to the full 1,000 HREP stake before frontend fees can accrue again.

Start with SDK for implementation details, then come back here when you are ready to run a fee-earning frontend operator.