> ## Documentation Index
> Fetch the complete documentation index at: https://kleros-mintlify-6ebc7975.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Install Kleros contracts, implement the arbitrable interface, and create your first dispute with V2 IArbitratorV2 or V1 ERC-792 on Arbitrum or Ethereum.

Kleros arbitration can be integrated on either protocol version:

* **V1** uses the ERC-792 arbitration standard (`IArbitrable` / `IArbitrator`) on Ethereum Mainnet and Gnosis Chain. See [ERC-792](/developers/arbitrable-apps/erc-792) and [ERC-1497](/developers/arbitrable-apps/erc-1497) for the full V1 standards.
* **V2** uses `IArbitrableV2` / `IArbitratorV2` on Arbitrum, with dispute templates and cross-chain support.

The steps below show both. Pick the version that matches the network you are deploying to. For contract addresses, see [Deployment Addresses](/reference/contracts/deployment-addresses-v1).

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @kleros/kleros-v2-contracts
  ```

  ```bash yarn theme={null}
  yarn add @kleros/kleros-v2-contracts
  ```

  ```bash forge theme={null}
  forge install kleros/kleros-v2-contracts
  ```
</CodeGroup>

## Contract Addresses (Arbitrum One)

```solidity theme={null}
// Core contracts
address constant KLEROS_CORE = 0x33d0b8879368acD8ca868e656Ade97bBcfeB12BA;
address constant DISPUTE_KIT_CLASSIC = 0x9c1dB86677E43Be2E1Af6D3b68D8B276D7E9b6E8;

// For cross-chain disputes
address constant HOME_GATEWAY = 0x9c1dB86677E43Be2E1Af6D3b68D8B276D7E9b6E8;
```

<Warning>
  Always verify addresses on the [official repository](https://github.com/kleros/kleros-v2) before deploying to production.
</Warning>

## Minimal Integration

### Step 1: Implement the arbitrable interface

<Tabs>
  <Tab title="V2 (IArbitrableV2)">
    ```solidity theme={null}
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;

    import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitrableV2.sol";
    import "@kleros/kleros-v2-contracts/arbitration/interfaces/IArbitratorV2.sol";

    contract MyArbitrable is IArbitrableV2 {
        IArbitratorV2 public immutable arbitrator;
        
        mapping(uint256 => uint256) public externalIDtoLocalID;
        mapping(uint256 => bool) public resolved;
        
        constructor(IArbitratorV2 _arbitrator) {
            arbitrator = _arbitrator;
        }
        
        function createDispute(
            bytes calldata _extraData
        ) external payable returns (uint256 disputeID) {
            uint256 cost = arbitrator.arbitrationCost(_extraData);
            require(msg.value >= cost, "Insufficient fee");
            
            disputeID = arbitrator.createDispute{value: cost}(
                2,          // numberOfChoices (e.g., 2 for binary)
                _extraData  // court parameters
            );
            
            // Map arbitrator's ID to your local tracking
            externalIDtoLocalID[disputeID] = /* your local ID */;
            
            emit DisputeRequest(arbitrator, disputeID, /* params */);
        }
        
        function rule(uint256 _disputeID, uint256 _ruling) external override {
            require(msg.sender == address(arbitrator), "Only arbitrator");
            require(!resolved[_disputeID], "Already resolved");
            
            resolved[_disputeID] = true;
            
            // Execute your business logic based on _ruling
            // 0 = refused to rule, 1+ = actual ruling choices
            
            emit Ruling(arbitrator, _disputeID, _ruling);
        }
    }
    ```
  </Tab>

  <Tab title="V1 (ERC-792)">
    ```solidity theme={null}
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.7.0;

    import "@kleros/erc-792/contracts/IArbitrable.sol";
    import "@kleros/erc-792/contracts/IArbitrator.sol";
    import "@kleros/erc-792/contracts/erc-1497/IEvidence.sol";

    contract MyArbitrable is IArbitrable, IEvidence {
        IArbitrator public arbitrator;
        
        mapping(uint256 => bool) public resolved;
        
        constructor(IArbitrator _arbitrator) {
            arbitrator = _arbitrator;
        }
        
        function createDispute(
            bytes memory _extraData,
            string memory _metaEvidence
        ) public payable returns (uint256 disputeID) {
            uint256 cost = arbitrator.arbitrationCost(_extraData);
            require(msg.value >= cost, "Insufficient fee");
            
            // numberOfChoices (e.g., 2 for binary) + court params in _extraData
            disputeID = arbitrator.createDispute{value: cost}(2, _extraData);
            
            emit MetaEvidence(disputeID, _metaEvidence);
            emit Dispute(arbitrator, disputeID, disputeID, disputeID);
        }
        
        function rule(uint256 _disputeID, uint256 _ruling) external override {
            require(msg.sender == address(arbitrator), "Only arbitrator");
            require(!resolved[_disputeID], "Already resolved");
            
            resolved[_disputeID] = true;
            
            // Execute your business logic based on _ruling
            // 0 = refused to rule, 1+ = actual ruling choices
            
            emit Ruling(arbitrator, _disputeID, _ruling);
        }
    }
    ```
  </Tab>
</Tabs>

### Step 2: Encode Extra Data

The `extraData` parameter specifies which court and how many jurors:

```solidity theme={null}
function getExtraData(
    uint96 courtID,
    uint256 minJurors
) public pure returns (bytes memory) {
    return abi.encodePacked(courtID, minJurors);
}

// Example: General Court (ID 1) with 3 jurors
bytes memory extraData = getExtraData(1, 3);
```

### Step 3: Get Arbitration Cost

```solidity theme={null}
function getArbitrationCost(bytes calldata extraData) external view returns (uint256) {
    return arbitrator.arbitrationCost(extraData);
}
```

## Court IDs

| Court                | ID     | Min Stake               | Use Case                |
| -------------------- | ------ | ----------------------- | ----------------------- |
| General              | 1      | 200 PNK                 | Default, broad disputes |
| Blockchain Technical | Higher | Smart contract disputes |                         |
| Curation             | Varies | Registry disputes       |                         |

<Tip>
  Start with **General Court (ID: 1)** for testing. Use `minJurors = 3` for most cases.
</Tip>

## Dispute Templates

Jurors need context. Create a template that describes the dispute:

```json theme={null}
{
  "title": "Payment Dispute: Order #1234",
  "description": "Buyer claims goods not delivered...",
  "question": "Should the escrowed funds be released to the seller?",
  "answers": [
    { "id": "0x1", "title": "Yes", "description": "Release to seller" },
    { "id": "0x2", "title": "No", "description": "Refund to buyer" }
  ]
}
```

Register templates on-chain or reference via IPFS URI.

## Testing

<Steps>
  <Step title="Use Arbitrum Sepolia">
    Deploy to testnet first. Get Arbitrum Sepolia ETH from a public faucet such as the [Arbitrum faucets list](https://docs.arbitrum.io/for-devs/dev-tools-and-resources/chain-info)
  </Step>

  <Step title="Get Test PNK">
    Testnet PNK is available from the Kleros faucet
  </Step>

  <Step title="Create a Test Dispute">
    Call `createDispute()` with test ETH for fees
  </Step>
</Steps>

## SDK (Optional)

For frontend integration, use the Kleros SDK:

```typescript theme={null}
import { KlerosSDK } from '@kleros/kleros-v2-sdk';

const sdk = new KlerosSDK({ chainId: 42161 });

// Get dispute details
const dispute = await sdk.getDispute(disputeID);

// Submit evidence
await sdk.submitEvidence(disputeID, evidenceURI);
```

## Next Steps

<Card title="Architecture Deep Dive" icon="sitemap" href="/developers/architecture">
  Understand how KlerosCore, Dispute Kits, and Sortition Module work together
</Card>
