Skip to content

Repository files navigation

@rakelabs/disputes-sdk

Build Kleros-facing dispute workflows from a TypeScript app. The SDK prepares unsigned transactions for dispute creation, evidence submission, meta-evidence amendments, appeals, and event decoding; your user's wallet remains responsible for signing and broadcasting.

The SDK never holds private keys and never takes custody of funds.

Your app -> Disputes SDK -> unsigned transaction -> user wallet -> blockchain

Install

# Choose one integration. The SDK core has no Ethers or Viem dependency.
npm install @rakelabs/disputes-sdk @rakelabs/ethers-adapter ethers
# or
npm install @rakelabs/disputes-sdk @rakelabs/viem-adapter viem

Requirements:

  • Node.js 20+
  • an RPC client and ABI codec supplied by your wallet/RPC integration
  • ethers is only needed for the ethers adapter shown below; viem integrations can be used instead

What You Build With It

Use this package when your application needs a standalone Kleros dispute contract:

  • choose Kleros court parameters with extraData,
  • publish or reference a MetaEvidence URI,
  • create a dispute with a fixed number of ruling options,
  • submit evidence documents,
  • read dispute state, evidence timelines, rulings, and events,
  • prepare appeal transactions when the ruling can be appealed.

If your product is specifically escrow or payment oriented, start with @rakelabs/klescrow-sdk or @rakelabs/dpayments-sdk. Use this package when you need direct dispute primitives.

Quick Start

import { BrowserProvider } from 'ethers';
import { Disputes, ABI, extraData } from '@rakelabs/disputes-sdk';
import {
  createEthersRpcClient,
  createEthersAbiCodec,
} from '@rakelabs/ethers-adapter';

const provider = new BrowserProvider(window.ethereum);
await provider.send('eth_requestAccounts', []);

const signer = await provider.getSigner();
const walletAddress = await signer.getAddress();

const rpc = createEthersRpcClient(provider);
const codec = createEthersAbiCodec(ABI);
const disputes = await Disputes.fromRpc(rpc, { codec, walletAddress });

const arbitratorExtraData = extraData.generalCourt();
const estimate = await disputes.factory.estimateCost(arbitratorExtraData);

console.log('Total dispute cost:', estimate.total.toString());

const { tx, disputeId } = await disputes.factory.prepareCreateDispute({
  arbitratorExtraData,
  metaEvidenceUri: 'ipfs://QmYourMetaEvidenceDocument',
  numberOfRulingOptions: 2n,
});

console.log(tx.preview);

const response = await signer.sendTransaction({
  to: tx.to,
  data: tx.data,
  value: BigInt(tx.value),
});
await response.wait();

const created = (await disputes.factory.getLogs(0, 'latest'))
  .find((event) => event.disputeId === disputeId);

if (!created) {
  throw new Error('Dispute creation event was not found');
}

const dispute = disputes.dispute(created.instance);

MetaEvidence and Evidence

Kleros workflows usually have two document layers:

  • MetaEvidence describes the dispute category, question, policy, and ruling options.
  • Evidence describes the proof submitted for one specific dispute.

Use @rakelabs/evidence-publisher to build and publish both document types to IPFS, then pass the returned ipfs://... URIs into this SDK.

Common Flows

Read State

const info = await dispute.read();

console.log(info.state);
console.log(info.owner);
console.log(info.providerDisputeId);
console.log(info.numberOfRulingOptions);

Submit Evidence

const evidenceTx = dispute.submitEvidence('ipfs://QmYourEvidenceDocument');
console.log(evidenceTx.preview);

await signer.sendTransaction({
  to: evidenceTx.to,
  data: evidenceTx.data,
  value: BigInt(evidenceTx.value),
});

Read Evidence Timeline

const timeline = await dispute.getEvidenceTimeline(0, 'latest');

for (const event of timeline) {
  console.log(event.submittedAt, event.party, event.evidenceUri);
}

Appeal

const [appealFeeWei, appealPeriod] = await Promise.all([
  dispute.appealCost(),
  dispute.appealPeriod(),
]);

if (appealPeriod.end === 0n) {
  throw new Error('No appeal window is currently open');
}

const appealTx = dispute.appeal('0x', appealFeeWei);
await signer.sendTransaction({
  to: appealTx.to,
  data: appealTx.data,
  value: BigInt(appealTx.value),
});

Arbitrator Extra Data

Kleros uses extraData to select the court and minimum juror count.

import {
  buildArbitratorExtraData,
  parseArbitratorExtraData,
  extraData,
} from '@rakelabs/disputes-sdk';

const encoded = buildArbitratorExtraData(0, 3);
const generalCourt = extraData.generalCourt();
const decoded = parseArbitratorExtraData(encoded);

console.log(generalCourt, decoded.subcourtId, decoded.minJurors);

Errors

The core SDK does not inspect wallet/provider exceptions. Your ethers or viem integration should extract revert data and pass it to its ABI codec.

import { decodeEthersError } from '@rakelabs/ethers-adapter';

try {
  await signer.sendTransaction({
    to: tx.to,
    data: tx.data,
    value: BigInt(tx.value),
  });
} catch (err) {
  const decoded = decodeEthersError(err, codec);
  if (decoded) {
    console.error(decoded.name, decoded.args);
  }
}

Documentation

This README and the linked guides describe the unreleased 0.2.0 API until that version is tagged. For 0.1.x usage, open the matching Git release tag.

Document Use it for
docs/reference.md API reference, types, actions, events, and common mistakes
docs/advanced.md Reader, transaction builder, multicall, and implementation selection
docs/migration-0.1-to-0.2.md Migrate from provider-based initialization
docs/on-chain.md Contract-level behavior and event model

Safety Notes

  • Always show tx.preview before requesting a signature.
  • Store the dispute contract address after creation; it is the canonical on-chain handle.
  • Publish durable MetaEvidence and Evidence URIs before submitting them on-chain.
  • Check chain IDs, court parameters, ruling options, and contract addresses before sending transactions.
  • This software interacts with autonomous contracts. Users transact at their own risk.

About

Programmable On-chain Disputes

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages