Build on Allora
Build a Reputer

Build a Reputer

Reputers are the Allora Network's source of truth. Each epoch, a reputer fetches the network's inferences for its topic, compares them against ground truth obtained from its own data sources, computes losses using the topic's loss method, and submits the resulting loss bundle on-chain. Reputers must stake ALLO, and rewards depend on accuracy relative to reputer consensus and on stake.

Reputers run on the allora-offchain-node (opens in a new tab), which handles registration, staking, submission windows, and transaction retries. You supply two HTTP services: one that returns the ground truth and one that computes the loss.

Goal

Run a reputer for a topic with allora-offchain-node: configure the node, point it at your ground-truth and loss-function services, put stake behind it, and verify your registration, stake, and EMA score.

Prerequisites

  • Git and Docker (with Docker Compose)
  • A wallet mnemonic — or let the node create keys for you on first run
  • ALLO on the target network to register and stake — on testnet, request funds from the Allora Testnet Faucet (opens in a new tab)
  • The ID of the topic you want to provide ground truth for
  • The allorad CLI for verification commands

Steps

1. Clone the node and create your config

git clone https://github.com/allora-network/allora-offchain-node.git
cd allora-offchain-node
cp config.example.json config.json

2. Configure your wallet

In config.json, fill in the wallet section:

  • addressKeyName: a wallet name of your choice — required; the node's init.config script exits with an error if it is empty.
  • addressRestoreMnemonic: the mnemonic of your existing wallet, or leave it empty to have a new key created automatically under addressKeyName — the generated address is written to ./data/env_file, and you will need to fund it before the node can register and stake.
  • nodeRpcs and nodegRpcs: lists of RPC and gRPC endpoints for the target network (the example config points at testnet). See Networks for endpoints.

3. Configure the reputer

The reputer section of config.json is an array with one entry per topic. This is the shape from config.example.json:

"reputer": [
  {
    "topicId": 1,
    "groundTruthEntrypointName": "apiAdapter",
    "lossFunctionEntrypointName": "apiAdapter",
    "minStake": 100000000,
    "groundTruthParameters": {
      "GroundTruthEndpoint": "http://localhost:8888/gt/{Token}/{BlockHeight}",
      "LabeledGroundTruthEndpoint": "http://localhost:8888/lgt/{Token}/{BlockHeight}",
      "Token": "ETHUSD"
    },
    "lossFunctionParameters": {
      "LossFunctionService": "http://localhost:5000",
      "LabeledLossFunctionService": "http://localhost:5000/labeled",
      "LossMethodOptions": {
        "loss_method": "sqe"
      }
    }
  }
]
  • topicId: the topic your reputer provides ground truth for.
  • groundTruthEntrypointName / lossFunctionEntrypointName: which adapter the node uses to reach your services. apiAdapter calls them over HTTP (see the adapter directory (opens in a new tab)).
  • minStake: the stake (in uallo) the node ensures is placed for your reputer on the topic. If your existing stake is below this amount, the node pulls the difference from your wallet. Set it at or above the chain's required_minimum_stake parameter — below that minimum, your contributions to reputation scoring are ignored and you earn no rewards.
  • groundTruthParameters: GroundTruthEndpoint is the URL of your ground-truth service; it supports the {Token}, {TopicId}, and {BlockHeight} template variables, where extra variables such as Token are defined alongside it in the same block.
  • lossFunctionParameters: LossFunctionService is the base URL of your loss service. LossMethodOptions.loss_method must be the loss method the topic declares in its on-chain configuration; any additional options (for example "delta": "1.0" for a Huber loss) are passed through to your loss service unchanged.

Whether the scalar or the Labeled* endpoints are used is decided by the topic's on-chain output arity: SINGLE topics use GroundTruthEndpoint and LossFunctionService, while multi-label (MULTI) topics — classification topics, for example — use LabeledGroundTruthEndpoint and LabeledLossFunctionService.

To run a reputer only, configure just the reputer array — the worker section of the example config is for the node's legacy inference-worker mode (see Migrate from the Offchain Node) and can be removed.

4. Serve ground truth and losses over HTTP

Your two services implement a small contract, documented in the API adapter README (opens in a new tab):

  • The ground-truth endpoint returns the true value for the requested block height as plain text (a single scalar for SINGLE topics). For example, a reputer on an ETH price topic would return the actual ETH price at the epoch's block height.
  • The loss-function service exposes two endpoints, created by appending to the configured base URL: /calculate, which receives the ground truth (y_true), a predicted value (y_pred), and your LossMethodOptions, and returns the loss; and /is_never_negative, which tells the node whether the loss method can produce negative values.

The node calls your ground-truth service once per epoch and your loss service for every value in the epoch's inference bundle — the combined network inference, each worker's individual inference, and the one-out variants the network uses for scoring.

5. Fund, initialize, and start the node

Load your config into the environment:

chmod +x init.config
./init.config

If you let the node create keys in step 2, fund the address recorded in ./data/env_file now (on testnet, use the faucet (opens in a new tab)). Re-run ./init.config after any change to config.json. Then start everything:

docker compose up --build

On startup the node registers your reputer on each configured topic and tops your stake up to minStake. It then submits a loss bundle every epoch — reputer submission windows are one full topic epoch long.

Coming to the Python SDK. As of allora_sdk 1.0.6 (the latest release on PyPI), the SDK's AlloraWorker supports the inferer role only, so reputers run on the offchain node. A reputer mode is under development on the allora-sdk-py (opens in a new tab) dev branch and is not yet released: AlloraWorker.reputer(...) will take a reputer function — built from a ground-truth function and a loss function via the make_reputer_function(get_ground_truth, loss_fn) helper — and automate the fetch–compute–submit cycle, including stake top-ups. It also ships default implementations of the loss methods used on the network: squared error (sqe/mse), absolute error (abse/mae), Huber (huber), log-cosh (logcosh), binary cross-entropy (bce), Poisson (poisson), and the z-transformed variants ztae and zptae (which require the standard deviation of historical values). This page will be updated when SDK reputer support is published.

Verify

Check your reputer's registration and stake with allorad, as described in How to Query Reputer Data:

allorad q emissions is-reputer-registered [topic_id] [address] --node https://allora-rpc.testnet.allora.network/
allorad q emissions stake-in-topic-reputer [address] [topic_id] --node https://allora-rpc.testnet.allora.network/

is-reputer-registered should return true, and your stake should be at least the minStake you configured. Once the node is submitting loss bundles, track your EMA score and compare it against the lowest score in the topic's active set to confirm you are eligible for rewards — see query EMA scores with allorad.

Troubleshoot

  • Registration or staking fails with an insufficient-funds error — the wallet must hold ALLO on the network you target. On testnet, request funds from the faucet (opens in a new tab), then restart the node.
  • The node fails at startup with a missing-endpoint error — the topic's output arity requires an endpoint you have not configured. SINGLE topics need GroundTruthEndpoint and LossFunctionService; MULTI topics need LabeledGroundTruthEndpoint and LabeledLossFunctionService.
  • Submissions are rejected for a whitelisted topic — the node checks whether your address is whitelisted before submitting. If the topic enforces a reputer whitelist, ask the topic creator to whitelist your address.
  • Registered and submitting, but no rewards — verify your stake meets the chain's required_minimum_stake; below it, your contributions are ignored. Also compare your EMA score against the topic's active set as shown in query EMA scores with allorad.
  • Chain version errors — the current node targets the v10 Allora chain emissions API and is not backward-compatible with v9 chains. Run the latest node release against a v10 network.

Next