verifier setup

Verifiers are independent consensus nodes that evaluate provider execution results using 0G TeeML (Trusted Execution Environment Machine Learning). They stake native 0G on-chain as economic collateral, ensuring accountability for their attestation decisions.


Prerequisites

  • Node.js 18+ installed
  • The halot CLI installed and linked (see CLI setup)
  • 0G testnet tokens for staking and gas
  • Access to 0G testnet and a supported TeeML chatbot model for verifier inference

1. Initialization

Initialize your verifier workspace. This generates several configuration files:

bash
$ halot verifier init
$ halot verifier init --testnet
$ halot verifier init --mainnet

# Output:
# HALOT
# Verifier workspace initialized
# Cluster: testnet
# Actor       0g:testnet
# 0G Wallet   0x1234...abcd
# Stellar     GABCD...WXYZ
# Settlement  0g:testnet, stellar:testnet

Generated files

FilePurpose
wallets.jsonNetwork-scoped private keys for 0G and Stellar. Never share this file.
halot.verifier.jsonVerifier identity, actor authority, stake config, and settlement wallet addresses.
model.config.jsonTeeML evaluation model settings (0G model name and SDK config).
inference.jsonPrompt template for how the verifier evaluates job results.
specializations.jsonCategories and service IDs this verifier is specialized for.

2. Configuration

halot.verifier.json

The main verifier config defines your identity, chosen Halot actor authority, stake parameters, and payout wallets.

json
{
  "verifierId": "",
  "displayName": "My Verifier",
  "description": "Text service verification specialist",
  "identity": {
    "domain": "myverifier.0g",
    "domainType": "space-id",
    "ownerAddress": "0x...",
    "erc8004TokenId": "",
    "agentRegistry": "",
    "agentUri": ""
  },
  "authority": {
    "path": "./wallets.json",
    "actor": "0g:testnet"
  },
  "settlementWallets": {
    "0g:testnet": "0x...",
    "stellar:testnet": "GABCD...WXYZ"
  },
  "stake": {
    "amount": "1000",
    "token": "0G",
    "status": "unlocked"
  },
  "fees": {
    "computeBudgetPerJob": "0.50"
  }
}

Key fields

FieldDescription
displayNameHuman-readable name for your verifier node.
identity.domainYour .0g domain via SPACE ID.
stake.amountAmount of 0G stake collateral to lock in the verifier registry. It affects eligibility and slashable collateral, not random-selection weight in the current registry.
authority.actorWhich 0G authority in wallets.json signs verifier actor-auth requests and final attestations.
fees.computeBudgetPerJobMax compute cost per verification job (in 0G tokens).

model.config.json

Configures how verifier evaluation runs. Use local for local signed evaluation, or testnet / mainnet to run through 0G TeeML. Set model to a supported 0G TeeML chatbot model for network modes.

json
{
  "evaluationMode": "testnet",
  "evaluationModel": {
    "model": "openai/gpt-oss-20b"
  },
  "sdk": {
    "network": "testnet"
  },
  "timeout": 60
}

The verifier runtime model and prompt stay in the local workspace. Registration reads those files plus wallets.json, then derives the verifier signing public key from authority.actor automatically.

Current 0G testnet TeeML chatbot models include openai/gpt-oss-20b, google/gemma-3-27b-it, and qwen/qwen-2.5-7b-instruct.

Required

evaluationMode must be local, testnet, or mainnet. In network modes, evaluationModel.model must match a live 0G TeeML chatbot model.

inference.json

Defines how the verifier evaluates job results. The template is sent to TeeML alongside the provider's output for evaluation.

json
{
  "systemPrompt": "You are a Halot verifier for paid text-generation services. Be strict, evidence-based, and deterministic. Return only valid JSON.",
  "promptTemplate": "Evaluate this Halot text-generation job.\n\nService:\n- ID: {{serviceId}}\n- Name: {{serviceName}}\n- Description: {{serviceDescription}}\n- Category: {{serviceCategory}}\n- Trust level: {{trustLevel}}\n\nRequester input:\n{{input}}\n\nProvider result:\n{{result}}\n\nService acceptance criteria:\n{{acceptanceCriteria}}\n\nExpected output schema:\n{{outputSchema}}\n\nInput artifacts:\n{{inputArtifacts}}\n\nResult artifacts:\n{{resultArtifacts}}\n\nArtifact validation issues:\n{{artifactValidationIssues}}\n\nDecision rules:\n- Approve only if the result directly fulfills the requester input, matches the expected output schema, and satisfies the acceptance criteria.\n- Reject if the result is empty, irrelevant, materially incomplete, malformed, unsafe, inaccessible, or artifact-mismatched.\n- Reject if required fields are missing, placeholder content is returned, or the answer contradicts the request.\n- Use uncertain only when the evidence is genuinely insufficient or the result is partially interpretable but not confidently approvable or rejectable.\n\nConfidence rules:\n- 0.90 to 1.00: clear outcome with strong evidence.\n- 0.70 to 0.89: likely outcome with minor ambiguity.\n- Below 0.70: use uncertain.\n\nReturn only JSON with fields:\n- decision\n- confidence\n- reason\n- failedCriteria",
  "outputSchema": {
    "decision": "approve | reject | uncertain",
    "confidence": "number between 0 and 1",
    "reason": "string",
    "failedCriteria": "array"
  },
  "maxTokens": 1024,
  "temperature": 0
}

specializations.json

Controls which types of jobs this verifier is eligible for.

json
{
  "categories": ["text"],
  "serviceIds": [],
  "maxConcurrentJobs": 3,
  "minConfidenceThreshold": 0.75
}

categories are the primary specialization filter. serviceIds is optional and narrows the verifier to specific services. maxConcurrentJobs now limits how many in-flight verification assignments Halot will give the verifier, and minConfidenceThreshold downgrades low-confidence model outputs to uncertain before submission.

3. Registration

Register your verifier with the network. The CLI reads the workspace files, registers the verifier with the aggregator, and stakes through the 0G verifier registry. On mainnet it also registers the configured .0g domain and Agent ID; on testnet those identity-registration steps are skipped.

bash
$ halot verifier register

# On mainnet this performs 4 steps:
#   1. Register .0g domain (SPACE ID)
#   2. Register verifier identity with the aggregator
#   3. Register Agent ID (ERC-8004)
#   4. Lock native 0G stake on the Verifier Registry contract
#
# On testnet, steps 1 and 3 are skipped.
#
# Output:
# Registered myverifier.0g (0xtx...)
# Registered Agent ID 123 (0xtx...)
# Registered verifier stake 0xtx...

The stake amount is read from halot.verifier.json → stake.amount. After registration, the stake status is updated to locked.

4. Running the node

Start the verifier process. It connects to the aggregator via SSE, receives verification assignments, evaluates results using TeeML, signs attestations with EIP-191, and submits them back to the network.

bash
# Start long-running verifier node
$ halot verifier run

# Custom polling interval
$ halot verifier run --interval 5000

# Process a single assignment and exit
$ halot verifier run --once

5. Verification flow

When a verification assignment arrives, the verifier node automatically:

1

TeeML Evaluation

Sends the job input, provider output, service schema, and acceptance criteria to the TeeML enclave for evaluation using your inference template.

2

Decision & Signing

The TeeML response is parsed into a decision (approve/reject), confidence score, reason, and failed criteria. An EIP-191 signature is produced over the attestation payload.

3

Attestation Submission

The signed attestation (with TEE proof) is submitted to the aggregator. Once the required quorum is reached, settlement proceeds automatically.

6. Unstaking

bash
# Initiate unstake (begins cooldown period)
$ halot verifier unstake

# Claim tokens after cooldown
$ halot verifier unstake --claim

# View verifier stats
$ halot verifier stats