From fc3d4ca670f35640e770b29f47d861c40d52ad97 Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Tue, 13 May 2025 04:49:11 +0200
Subject: [PATCH 1/2] feat: allow choosing the disputekit in the resolver flow
---
web/src/context/NewDisputeContext.tsx | 4 +-
.../NavigationButtons/SubmitDisputeButton.tsx | 7 +++-
web/src/pages/Resolver/Parameters/Court.tsx | 38 +++++++++++++++++--
3 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/web/src/context/NewDisputeContext.tsx b/web/src/context/NewDisputeContext.tsx
index f15e2440b..ccfdd9e9c 100644
--- a/web/src/context/NewDisputeContext.tsx
+++ b/web/src/context/NewDisputeContext.tsx
@@ -47,6 +47,7 @@ interface IDisputeData extends IDisputeTemplate {
numberOfJurors: number;
arbitrationCost?: string;
aliasesArray?: AliasArray[];
+ disputeKitId?: number;
}
interface INewDisputeContext {
@@ -71,6 +72,7 @@ const getInitialDisputeData = (): IDisputeData => ({
{ title: "", id: "2", description: "" },
],
aliasesArray: [{ name: "", address: "", id: "1" }],
+ disputeKitId: 1,
version: "1.0",
});
@@ -117,7 +119,7 @@ export const NewDisputeProvider: React.FC<{ children: React.ReactNode }> = ({ ch
const constructDisputeTemplate = (disputeData: IDisputeData) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { courtId, numberOfJurors, arbitrationCost, ...baseTemplate } = disputeData;
+ const { courtId, numberOfJurors, arbitrationCost, disputeKitId, ...baseTemplate } = disputeData;
if (!isUndefined(baseTemplate.aliasesArray)) {
baseTemplate.aliasesArray = baseTemplate.aliasesArray.filter((item) => item.address !== "" && item.isValid);
diff --git a/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx b/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx
index 5db0a357f..f2ad186b4 100644
--- a/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx
+++ b/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx
@@ -42,13 +42,16 @@ const SubmitDisputeButton: React.FC = () => {
return userBalance && userBalance.value < arbitrationCost;
}, [userBalance, disputeData]);
- // TODO: decide which dispute kit to use
const { data: submitCaseConfig, error } = useSimulateDisputeResolverCreateDisputeForTemplate({
query: {
enabled: !insufficientBalance && isTemplateValid(disputeTemplate),
},
args: [
- prepareArbitratorExtradata(disputeData.courtId ?? "1", disputeData.numberOfJurors ?? "", 1),
+ prepareArbitratorExtradata(
+ disputeData.courtId ?? "1",
+ disputeData.numberOfJurors ?? "",
+ disputeData.disputeKitId ?? 1
+ ),
JSON.stringify(disputeTemplate),
"",
BigInt(disputeTemplate.answers.length),
diff --git a/web/src/pages/Resolver/Parameters/Court.tsx b/web/src/pages/Resolver/Parameters/Court.tsx
index c9b3b568d..1bad50ec0 100644
--- a/web/src/pages/Resolver/Parameters/Court.tsx
+++ b/web/src/pages/Resolver/Parameters/Court.tsx
@@ -1,7 +1,7 @@
import React, { useMemo } from "react";
import styled, { css } from "styled-components";
-import { AlertMessage, DropdownCascader } from "@kleros/ui-components-library";
+import { AlertMessage, DropdownCascader, DropdownSelect } from "@kleros/ui-components-library";
import { useNewDisputeContext } from "context/NewDisputeContext";
import { rootCourtToItems, useCourtTree } from "hooks/queries/useCourtTree";
@@ -14,6 +14,7 @@ import { StyledSkeleton } from "components/StyledSkeleton";
import Header from "pages/Resolver/Header";
import NavigationButtons from "../NavigationButtons";
+import { isKlerosNeo, isKlerosUniversity, isTestnetDeployment } from "src/consts";
const Container = styled.div`
display: flex;
@@ -49,28 +50,56 @@ const AlertMessageContainer = styled.div`
margin-top: 24px;
`;
+const StyledDropdownSelect = styled(DropdownSelect)`
+ width: 84vw;
+ margin-top: 24px;
+ ${landscapeStyle(
+ () => css`
+ width: ${responsiveSize(442, 700, 900)};
+ `
+ )}
+`;
+
const Court: React.FC = () => {
const { disputeData, setDisputeData } = useNewDisputeContext();
const { data } = useCourtTree();
const items = useMemo(() => !isUndefined(data?.court) && [rootCourtToItems(data.court)], [data]);
- const handleWrite = (courtId: string) => {
- setDisputeData({ ...disputeData, courtId: courtId });
+ const disputeKitOptions = useMemo(() => {
+ if (isKlerosUniversity()) return [{ text: "Classic Dispute Kit", value: 1 }];
+ if (isKlerosNeo()) return [{ text: "Classic Dispute Kit", value: 1 }];
+ if (isTestnetDeployment()) return [{ text: "Classic Dispute Kit", value: 1 }];
+ const options = [{ text: "Classic Dispute Kit", value: 1 }];
+ if (disputeData.courtId === "1") options.push({ text: "Shutter Dispute Kit", value: 2 });
+ return options;
+ }, [disputeData.courtId]);
+
+ const handleCourtWrite = (courtId: string) => {
+ const newDisputeKitId = courtId === "1" ? (disputeData.disputeKitId ?? 1) : 1;
+ setDisputeData({ ...disputeData, courtId, disputeKitId: newDisputeKitId });
};
+ const handleDisputeKitChange = (newValue: string | number) =>
+ setDisputeData({ ...disputeData, disputeKitId: Number(newValue) });
+
return (
{items ? (
typeof path === "string" && handleWrite(path.split("/").pop()!)}
+ onSelect={(path: string | number) => typeof path === "string" && handleCourtWrite(path.split("/").pop()!)}
placeholder="Select Court"
value={`/courts/${disputeData.courtId}`}
/>
) : (
)}
+
{
);
};
+
export default Court;
From 0c96fa268abbccd26c9c6ba3cdce401e45d0d1ff Mon Sep 17 00:00:00 2001
From: kemuru <102478601+kemuru@users.noreply.github.com>
Date: Tue, 13 May 2025 18:46:39 +0200
Subject: [PATCH 2/2] chore: improvement in disputekitid fetching and showing
---
web/src/consts/index.ts | 12 ++++++++
.../hooks/queries/useSupportedDisputeKits.ts | 29 +++++++++++++++++++
web/src/pages/Resolver/Parameters/Court.tsx | 27 ++++++++---------
3 files changed, 53 insertions(+), 15 deletions(-)
create mode 100644 web/src/hooks/queries/useSupportedDisputeKits.ts
diff --git a/web/src/consts/index.ts b/web/src/consts/index.ts
index 219ff0e9c..0064f4a98 100644
--- a/web/src/consts/index.ts
+++ b/web/src/consts/index.ts
@@ -42,3 +42,15 @@ export const INVALID_DISPUTE_DATA_ERROR = `The dispute data is not valid, please
export const RPC_ERROR = `RPC Error: Unable to fetch dispute data. Please avoid voting.`;
export const spamEvidencesIds: string[] = (import.meta.env.REACT_APP_SPAM_EVIDENCES_IDS ?? "").split(",");
+
+export const getDisputeKitName = (id: number): string | undefined => {
+ const universityDisputeKits: Record = { 1: "Classic Dispute Kit" };
+ const neoDisputeKits: Record = { 1: "Classic Dispute Kit" };
+ const testnetDisputeKits: Record = { 1: "Classic Dispute Kit" };
+ const devnetDisputeKits: Record = { 1: "Classic Dispute Kit", 2: "Shutter Dispute Kit" };
+
+ if (isKlerosUniversity()) return universityDisputeKits[id];
+ if (isKlerosNeo()) return neoDisputeKits[id];
+ if (isTestnetDeployment()) return testnetDisputeKits[id];
+ return devnetDisputeKits[id];
+};
diff --git a/web/src/hooks/queries/useSupportedDisputeKits.ts b/web/src/hooks/queries/useSupportedDisputeKits.ts
new file mode 100644
index 000000000..d8aed6603
--- /dev/null
+++ b/web/src/hooks/queries/useSupportedDisputeKits.ts
@@ -0,0 +1,29 @@
+import { useQuery } from "@tanstack/react-query";
+import { useGraphqlBatcher } from "context/GraphqlBatcher";
+import { graphql } from "src/graphql";
+import { SupportedDisputeKitsQuery } from "src/graphql/graphql";
+
+const supportedDisputeKitsQuery = graphql(`
+ query SupportedDisputeKits($id: ID!) {
+ court(id: $id) {
+ supportedDisputeKits {
+ id
+ }
+ }
+ }
+`);
+
+export const useSupportedDisputeKits = (courtId?: string) => {
+ const { graphqlBatcher } = useGraphqlBatcher();
+ return useQuery({
+ enabled: !!courtId,
+ queryKey: ["SupportedDisputeKits", courtId],
+ staleTime: Infinity,
+ queryFn: async () =>
+ await graphqlBatcher.fetch({
+ id: crypto.randomUUID(),
+ document: supportedDisputeKitsQuery,
+ variables: { id: courtId },
+ }),
+ });
+};
diff --git a/web/src/pages/Resolver/Parameters/Court.tsx b/web/src/pages/Resolver/Parameters/Court.tsx
index 1bad50ec0..5d6274388 100644
--- a/web/src/pages/Resolver/Parameters/Court.tsx
+++ b/web/src/pages/Resolver/Parameters/Court.tsx
@@ -5,6 +5,8 @@ import { AlertMessage, DropdownCascader, DropdownSelect } from "@kleros/ui-compo
import { useNewDisputeContext } from "context/NewDisputeContext";
import { rootCourtToItems, useCourtTree } from "hooks/queries/useCourtTree";
+import { useSupportedDisputeKits } from "queries/useSupportedDisputeKits";
+import { getDisputeKitName } from "consts/index";
import { isUndefined } from "utils/index";
import { landscapeStyle } from "styles/landscapeStyle";
@@ -14,7 +16,6 @@ import { StyledSkeleton } from "components/StyledSkeleton";
import Header from "pages/Resolver/Header";
import NavigationButtons from "../NavigationButtons";
-import { isKlerosNeo, isKlerosUniversity, isTestnetDeployment } from "src/consts";
const Container = styled.div`
display: flex;
@@ -62,21 +63,15 @@ const StyledDropdownSelect = styled(DropdownSelect)`
const Court: React.FC = () => {
const { disputeData, setDisputeData } = useNewDisputeContext();
- const { data } = useCourtTree();
- const items = useMemo(() => !isUndefined(data?.court) && [rootCourtToItems(data.court)], [data]);
-
+ const { data: courtTree } = useCourtTree();
+ const { data: supportedDisputeKits } = useSupportedDisputeKits(disputeData.courtId);
+ const items = useMemo(() => !isUndefined(courtTree?.court) && [rootCourtToItems(courtTree.court)], [courtTree]);
const disputeKitOptions = useMemo(() => {
- if (isKlerosUniversity()) return [{ text: "Classic Dispute Kit", value: 1 }];
- if (isKlerosNeo()) return [{ text: "Classic Dispute Kit", value: 1 }];
- if (isTestnetDeployment()) return [{ text: "Classic Dispute Kit", value: 1 }];
- const options = [{ text: "Classic Dispute Kit", value: 1 }];
- if (disputeData.courtId === "1") options.push({ text: "Shutter Dispute Kit", value: 2 });
- return options;
- }, [disputeData.courtId]);
-
+ const supportedDisputeKitIDs = supportedDisputeKits?.court?.supportedDisputeKits.map((k) => Number(k.id)) || [];
+ return supportedDisputeKitIDs.map((id) => ({ text: getDisputeKitName(id), value: id }));
+ }, [supportedDisputeKits]);
const handleCourtWrite = (courtId: string) => {
- const newDisputeKitId = courtId === "1" ? (disputeData.disputeKitId ?? 1) : 1;
- setDisputeData({ ...disputeData, courtId, disputeKitId: newDisputeKitId });
+ setDisputeData({ ...disputeData, courtId, disputeKitId: undefined });
};
const handleDisputeKitChange = (newValue: string | number) =>
@@ -96,8 +91,10 @@ const Court: React.FC = () => {
)}