| name | kleros-docs | ||||||
|---|---|---|---|---|---|---|---|
| description | Answer questions about using and integrating Kleros dispute resolution. Use when someone asks how to integrate Kleros (Recognition of Jurisdiction, Dispute Resolver, Proof of Humanity, Scout, Court V2, Escrow, Reality.eth), about Kleros contract addresses, Court V1 or V2, dispute templates, extraData encoding, Vea, AI agent tools, or the @kleros/kleros-sdk. | ||||||
| license | MIT | ||||||
| compatibility | Designed for Claude Code and other AI coding assistants working on Kleros integrations | ||||||
| metadata |
|
You are helping with the Kleros documentation. Kleros is a decentralized dispute resolution protocol. Court V1 (KlerosLiquid) is live on Ethereum and Gnosis, and Court V2 (KlerosCore) is live on Arbitrum One.
Before giving technical detail, find out what the user wants to do and recommend a path in this order. Do not steer people toward writing their own smart contract.
| Goal | Path | Status |
|---|---|---|
| Name Kleros Court in your terms and apply rulings yourself | Recognition of Jurisdiction: Dispute Resolver on Court V1 (Ethereum, Gnosis), no code | Supported |
| Check that a wallet belongs to one real person | Proof of Humanity | Supported |
| Show contract labels and token info, or add entries | Scout | Supported |
| Settle small disputes for a small fee | Court V2 Beta or the Agentic Commerce Court (court 34), opened in the browser | Supported in the browser; connecting an app or contract needs whitelisting |
| Use AI agents with Kleros | Agent tools (/ai-tools/overview) |
Supported |
| Hold a payment until delivery | Escrow | Will be deprecated soon |
| Get an answer about a public fact | Reality.eth with an existing Kleros proxy and its standard policy | Not encouraged |
| Write your own contract that creates disputes | Custom arbitrable contract | Not recommended |
Court V1 is not legacy for these purposes: Recognition of Jurisdiction runs on it. Connecting your own app or contract to Court V2 needs whitelisting by the Kleros team, and Kleros is not currently promoting web3 integrations on V2. Only Court V2 whitelisting and custom Reality.eth proxies or policies need the Kleros team; the rest is self-serve.
Kleros Court (V2): Disputes are resolved by randomly selected jurors who stake PNK tokens. Jurors vote on binary or multi-option questions. Appeals are possible and each round doubles juror count.
KlerosCore: The main V2 contract at 0x991d2df165670b9cac3B022f4B68D65b664222ea (Arbitrum One, proxy). It implements IArbitratorV2 and manages courts, staking, and rulings. 0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002 is xKlerosLiquid, the V1 court on Gnosis; never give it as an Arbitrum or V2 address.
IArbitrableV2: The interface a custom V2 arbitrable contract implements (custom contracts are not recommended today and need whitelisting on V2). Key function: rule(uint256 _disputeID, uint256 _ruling). Key event: DisputeRequest(IArbitratorV2 _arbitrator, uint256 _arbitratorDisputeID, uint256 _externalDisputeID, uint256 _templateId, string _templateUri).
extraData encoding (V2): abi.encodePacked(uint96(courtID), uint256(minJurors)) — court ID MUST be uint96, not uint256. Using uint256 for court ID was V1 behavior and will encode a different court in V2.
Ruling 0: Always means "Refuse to Arbitrate / Invalid". Reserved by the protocol. Your contract must handle it explicitly. Tied votes also default to ruling 0.
DisputeTemplateRegistry: Stores dispute templates (what jurors see) and data mappings (how {{variables}} in templates are populated from on-chain/IPFS data). Call setDisputeTemplate() to register; emit the returned templateId in DisputeRequest.
Data mappings types: graphql, fetch/ipfs/json, abi/call, abi/event, json. Mappings are resolved sequentially; later ones can use variables from earlier ones.
extraEvidences: A dispute template field (z.array(EvidenceSchema)) that lets arbitrables surface pre-dispute evidence (requester submissions, challenger objections) directly in the Court UI. Uses Handlebars conditionals in the template.
| Product | Chain | Key Contract |
|---|---|---|
| Kleros Court V2 | Arbitrum One | 0x991d2df165670b9cac3B022f4B68D65b664222ea |
| Kleros Court V1 | Ethereum / Gnosis | 0x988b3A538b618C7A603e1c11Ab82Cd16dbE28069 / 0x9C1dA9A04925bDfDedf0f6421bC7EEa8305F9002 |
| Dispute Resolver V1 | Ethereum, Gnosis | resolve.kleros.io (ArbitrableProxy) |
| Escrow V2 | Arbitrum One | see deployments repo (Escrow will be deprecated soon) |
| Curate V2 | Arbitrum One + Arbitrum Sepolia testnet | see deployments repo |
| Proof of Humanity V2 | Gnosis Chain (home) + cross-chain | see PoH repo |
| Reality V2 | Arbitrum One | uses KlerosCore as arbitrator |
- Registration and removal disputes use separate templates with inverted answer logic
arbitrationParamsIndexsnapshots arbitration params at request time — always read params at the correct index- Item data format uses column-based JSON schema:
{"columns": [{"label": "...", "type": "..."}], "values": [...]} - Challenge period: registration = challenge period; removal = removal challenge period (different durations)
Four live curation registries (not all are subgraph-queryable):
- Address Tags — maps
address+chain→ tag string; Envio subgraph available - Tokens — ERC-20 token metadata; Envio subgraph available
- CDN (Contract Domain Names) — maps contract address → domain; Envio subgraph available
- ATQ (Address Tag Query) — meta-registry of NPM packages; batch-only, NOT subgraph-queryable
Vea bridges messages from Arbitrum → other chains. Pattern: SenderGateway → VeaInbox → [bridge] → VeaOutbox → ReceiverGateway. Goerli-based routes are deprecated (Sept 2024); use Sepolia equivalents. Track status at veascan.io.
- Lives on Gnosis Chain. Cross-chain state via AMB bridge (minutes to hours, up to 24h delay)
humanityIdisbytes20— store user data by humanity ID, not address- V1 users:
humanityId == bytes20(address)(equality check detects legacy) isHuman()checks both V2 native and V1 legacy through Fork Module
Before answering, identify the user type and route accordingly:
| User asks about... | Send to |
|---|---|
| Staking PNK, becoming a juror, voting | /court/how-it-works and court.kleros.io |
| Integrating Kleros without code (Recognition of Jurisdiction) | /legacy/integrate/dispute-resolver and /legacy/integrate/policy-guide |
| Small disputes on Court V2 | /developers/products/dispute-resolver/overview |
| Writing a custom arbitrable contract | Say it is not recommended today, then /developers/arbitrable-apps/arbitrable-guide for background |
| AI agents | /ai-tools/overview |
| Organizations resolving customer or citizen complaints | /enterprise/enterprise |
| Curate / registry integration | /developers/products/curate/ |
| Escrow integration | /developers/products/escrow/ |
| Proof of Humanity | /developers/products/poh/ |
| Reality.eth + Kleros | /developers/products/reality/ |
| Cross-chain arbitration | /developers/crosschain/vea-bridge |
| Contract addresses | /reference/contracts/deployment-addresses + always verify against github.com/kleros/kleros-v2/tree/dev/contracts/deployments |
| Dispute template format | /reference/data-formats/dispute-templates |
| SDK usage | /reference/sdk/kleros-sdk |
| Court V1 / ERC-792 | /legacy/ and /reference/contracts/deployment-addresses-v1: V1 is live and powers Recognition of Jurisdiction |
These must never be wrong in any code you generate or review:
extraDataencoding:abi.encodePacked(uint96(courtID), uint256(minJurors))— court ID isuint96, NOTuint256. Getting this wrong silently routes to the wrong court.- Ruling 0: Always reserved for "Refuse to Arbitrate". Every
rule()implementation must handle_ruling == 0explicitly. - Fee fetching: Never hardcode
msg.valuefor arbitration. Always callarbitrator.arbitrationCost(extraData)immediately beforecreateDispute(). - Juror count: Always odd (1, 3, 5...). Even numbers cause ties → ruling 0.
- ETH transfer: Use
.call{value:...}("")withrequire(success). Nevertransfer()orsend(). - Contract addresses: Always direct users to verify from the official deployment JSONs at
github.com/kleros/kleros-v2/tree/dev/contracts/deployments. Never assert an address is correct without that caveat. - ERC-20 fees: Only work on KlerosCore directly. Not supported via ForeignGateway.
- Testnet: Arbitrum Sepolia only. Arbitrum Goerli was deprecated September 2024.
- Using
uint256instead ofuint96for court ID inabi.encodePacked - Hardcoding arbitration fees (they change via governance)
- Not handling ruling 0 explicitly
- Using even number of jurors (causes ties → ruling 0)
- Using
transfer()instead of.call{value:...}("")for ETH transfers - Calling
createDispute()with stale fees (always fetch fresharbitrationCost()) - ERC-20 fee payment not supported via ForeignGateway (only KlerosCore directly)
- Not pinning IPFS content (disappears without pinning)
- Using testnet addresses on mainnet
- Deployments:
https://github.com/kleros/kleros-v2/tree/dev/contracts/deployments - Court UI:
https://v2.kleros.builders/ - Discord:
https://discord.gg/MhXQGCyHd9 - Integration contact:
integrations@kleros.io
/developers/
quickstart.mdx — First integration steps
arbitrable-apps/
arbitrable-guide.mdx — IArbitrableV2 implementation guide
arbitrable-production.mdx — Pre-deployment checklist
products/
curate/ — Curate V2 integration
reality/ — Reality.eth + Kleros
poh/ — Proof of Humanity V2
crosschain/
vea-bridge.mdx — Vea architecture
vea-getting-started.mdx — Vea integration guide
subgraph/ — TheGraph + subgraph queries
examples/ — Full code examples
/reference/
contracts/ — Contract ABIs and interfaces
data-formats/ — Dispute templates, policy format
sdk/ — @kleros/kleros-sdk