diff --git a/subgraph/scripts/update.sh b/subgraph/scripts/update.sh index 2c867c7..6c64970 100755 --- a/subgraph/scripts/update.sh +++ b/subgraph/scripts/update.sh @@ -25,12 +25,29 @@ function update() #hardhatNetwork #graphNetwork #dataSourceIndex #contract abiIndex=0 for f in $(yq e .dataSources[$dataSourceIndex].mapping.abis[].file subgraph.yaml -o json -I 0 | jq -sr '.[]') do - f2=$(echo $f | sed "s|\(.*\/deployments\/\).*\/|\1$hardhatNetwork\/|") + f2=$(echo "$f" | sed "s|\(.*\/deployments\/\).*\/|\1$hardhatNetwork\/|") yq -i ".dataSources[$dataSourceIndex].mapping.abis[$abiIndex].file=\"$f2\"" "$SCRIPT_DIR"/../subgraph.yaml (( ++abiIndex )) done } +function updateTemplates() #hardhatNetwork #templateIndex #contract +{ + local hardhatNetwork="$1" + local templateIndex="$2" + local contract="$3" + local artifact="$SCRIPT_DIR/../../contracts/deployments/$hardhatNetwork/$contract.json" + + # Set the ABIs path for this Hardhat network + abiIndex=0 + for f in $(yq e .templates[$templateIndex].mapping.abis[].file subgraph.yaml -o json -I 0 | jq -sr '.[]') + do + f2=$(echo "$f" | sed "s|\(.*\/deployments\/\).*\/|\1$hardhatNetwork\/|") + yq -i ".templates[$templateIndex].mapping.abis[$abiIndex].file=\"$f2\"" "$SCRIPT_DIR"/../subgraph.yaml + (( ++abiIndex )) + done +} + # as per ../contracts/hardhat.config.js hardhatNetwork=${1:-arbitrumSepolia} @@ -45,4 +62,11 @@ for contract in $(yq .dataSources[].name "$SCRIPT_DIR"/../subgraph.yaml) do update $hardhatNetwork $graphNetwork $i $contract (( ++i )) +done + +j=0 +for contract in $(yq .templates[].name "$SCRIPT_DIR"/../subgraph.yaml) +do + updateTemplates $hardhatNetwork $j $contract + (( ++j )) done \ No newline at end of file diff --git a/web/.gitignore b/web/.gitignore index 1c23ba3..0c88a7d 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -31,6 +31,7 @@ src/hooks/contracts src/graphql generatedGitInfo.json generatedNetlifyInfo.json +generatedMainCurateAddress.json # logs npm-debug.log* diff --git a/web/package.json b/web/package.json index 126e345..7f23d32 100644 --- a/web/package.json +++ b/web/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@graphql-codegen/cli": "^4.0.1", "@graphql-codegen/client-preset": "^4.2.0", + "@kleros/kleros-v2-contracts": "^0.3.2", "@netlify/functions": "^1.6.0", "@parcel/transformer-svg-react": "2.11.0", "@parcel/watcher": "~2.2.0", diff --git a/web/scripts/generateBuildInfo.sh b/web/scripts/generateBuildInfo.sh index 3822f82..9c58614 100755 --- a/web/scripts/generateBuildInfo.sh +++ b/web/scripts/generateBuildInfo.sh @@ -3,4 +3,30 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" jq -n --arg primeUri "$DEPLOY_PRIME_URL" --arg uri "$URL" --arg deployUri "$DEPLOY_URL" '{ netlifyDeployPrimeUri: $primeUri, netlifyUri: $uri, netlifyDeployUri: $deployUri }' > src/generatedNetlifyInfo.json + + +# Fetch main curate address from subgraph +if [ -z "$REACT_APP_ARBSEPOLIA_SUBGRAPH" ]; then + echo "Error: REACT_APP_ARBSEPOLIA_SUBGRAPH environment variable is not set." + exit 1 +fi + +QUERY='{"query":"{\n mainCurate(id:\"0\"){\n address\n }\n}","variables":{}}' + +OUTPUT_FILE="src/generatedMainCurateAddress.json" + +TEMP_FILE=$(mktemp) + +if curl "$REACT_APP_ARBSEPOLIA_SUBGRAPH" -s -X POST -H "Content-Type: application/json" --data "$QUERY" -o "$TEMP_FILE"; then + ADDRESS=$(jq -r '.data.mainCurate.address' "$TEMP_FILE") + echo "{\"mainCurateAddress\": \"$ADDRESS\"}" > "$OUTPUT_FILE" + + echo -e "✔ Main Curate address fetched and saved to $OUTPUT_FILE" +else + echo -e "❌ Error fetching Main curate address from $REACT_APP_ARBSEPOLIA_SUBGRAPH" + exit 1 +fi + +rm "$TEMP_FILE" + node "$SCRIPT_DIR/gitInfo.js" \ No newline at end of file diff --git a/web/src/assets/svgs/icons/check-circle-outline.svg b/web/src/assets/svgs/icons/check-circle-outline.svg index 7f5c00b..e4eef2e 100644 --- a/web/src/assets/svgs/icons/check-circle-outline.svg +++ b/web/src/assets/svgs/icons/check-circle-outline.svg @@ -1,4 +1,4 @@ - + diff --git a/web/src/components/ActionButton/index.tsx b/web/src/components/ActionButton/index.tsx index cd6d04f..eeb38eb 100644 --- a/web/src/components/ActionButton/index.tsx +++ b/web/src/components/ActionButton/index.tsx @@ -50,7 +50,7 @@ const ActionButton: React.FC = ({ status, registryAddress, itemId let ButtonComponent: JSX.Element | null = useMemo(() => { if (status === Status.Disputed) return ( - + ); @@ -59,7 +59,7 @@ const ActionButton: React.FC = ({ status, registryAddress, itemId return ; return ; - }, [isExecutable, registryAddress, status, itemId, isLoading, disputeId]); + }, [isExecutable, registryAddress, status, itemId, isLoading, disputeId, isItem, toggleModal, refetch]); return ( <> diff --git a/web/src/components/InformationCards/RegistryInformationCard/Policies.tsx b/web/src/components/InformationCards/RegistryInformationCard/Policies.tsx index ff1c345..ab8fc38 100644 --- a/web/src/components/InformationCards/RegistryInformationCard/Policies.tsx +++ b/web/src/components/InformationCards/RegistryInformationCard/Policies.tsx @@ -4,10 +4,9 @@ import { landscapeStyle } from "styles/landscapeStyle"; import Skeleton from "react-loading-skeleton"; import PolicyIcon from "svgs/icons/policy.svg"; import { responsiveSize } from "styles/responsiveSize"; -import { DEFAULT_CHAIN } from "consts/chains"; import { getIpfsUrl } from "utils/getIpfsUrl"; -import { listOfListsAddresses } from "utils/listOfListsAddresses"; import { useRegistryDetailsQuery } from "queries/useRegistryDetailsQuery"; +import { MAIN_CURATE_ADDRESS } from "src/consts"; const ShadeArea = styled.div` display: flex; @@ -61,7 +60,7 @@ interface IPolicies { } export const Policies: React.FC = ({ policyURI, isItem }) => { - const { data: parentRegistryDetails } = useRegistryDetailsQuery(listOfListsAddresses[DEFAULT_CHAIN]); + const { data: parentRegistryDetails } = useRegistryDetailsQuery(MAIN_CURATE_ADDRESS); return ( diff --git a/web/src/consts/arbitration.ts b/web/src/consts/arbitration.ts index 2c58434..1ae5ba1 100644 --- a/web/src/consts/arbitration.ts +++ b/web/src/consts/arbitration.ts @@ -1,4 +1,8 @@ -export const KLEROS_ARBITRATOR = "0xA54e7A16d7460e38a8F324eF46782FB520d58CE8"; +import { disputeTemplateRegistryAddress, evidenceModuleAddress, klerosCoreAddress } from "hooks/contracts/generated"; +import { DEFAULT_CHAIN } from "./chains"; + +export const KLEROS_ARBITRATOR = klerosCoreAddress[DEFAULT_CHAIN]; +export const EVIDENCE_MODULE = evidenceModuleAddress[DEFAULT_CHAIN]; +export const TEMPLATE_REGISTRY = disputeTemplateRegistryAddress[DEFAULT_CHAIN]; +// TODO: this would be ? export const KLEROS_GOVERNOR = "0xf1C7c037891525E360C59f708739Ac09A7670c59"; -export const EVIDENCE_MODULE = "0x57fd453FB0d16f8ca174E7386102D7170E17Be09"; -export const TEMPLATE_REGISTRY = "0x596D3B09E684D62217682216e9b7a0De75933391"; diff --git a/web/src/consts/index.ts b/web/src/consts/index.ts index 394e3c8..9f077c2 100644 --- a/web/src/consts/index.ts +++ b/web/src/consts/index.ts @@ -1,4 +1,5 @@ import { version, gitCommitHash, gitCommitShortHash, gitBranch, gitTags, clean } from "../generatedGitInfo.json"; +import GeneratedMainCurate from "../generatedMainCurateAddress.json"; export const ONE_BASIS_POINT = 10000n; export const IPFS_GATEWAY = process.env.REACT_APP_IPFS_GATEWAY || "https://cdn.kleros.link"; @@ -18,8 +19,9 @@ export const ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/; export const ETH_SIGNATURE_REGEX = /^0x[a-fA-F0-9]{130}$/; export const DEFAULT_LIST_LOGO = "ipfs://QmWfxEmfEWwM6LDgER2Qp2XZpK1MbDtNp7uGqCS4UPNtgJ/symbol-CURATE.png"; -export const CURATION_POLICY = `${IPFS_GATEWAY}/ipfs/QmWciZMi8mBJg34FapRHK4Yh7a6UqmxrpcKQ3KRNMXzjfx`; -export const COURT_SITE = "https://dev--kleros-v2.netlify.app/#/cases"; +export const COURT_SITE = process.env.COURT_SITE || "https://v2.kleros.builders"; export const SUPPORTED_FILE_TYPES = ["application/pdf", "text/rtf", "text/markdown", "text/plain"]; + +export const MAIN_CURATE_ADDRESS = GeneratedMainCurate.mainCurateAddress; diff --git a/web/src/layout/Header/navbar/Explore.tsx b/web/src/layout/Header/navbar/Explore.tsx index b18b3dd..e978a8a 100644 --- a/web/src/layout/Header/navbar/Explore.tsx +++ b/web/src/layout/Header/navbar/Explore.tsx @@ -1,9 +1,11 @@ -import React from "react"; +import React, { useMemo } from "react"; import styled, { css } from "styled-components"; import { landscapeStyle } from "styles/landscapeStyle"; import { Link, useLocation } from "react-router-dom"; import { useOpenContext } from "../MobileHeader"; -import { CURATION_POLICY } from "consts/index"; +import { IPFS_GATEWAY, MAIN_CURATE_ADDRESS } from "consts/index"; +import { useRegistryDetailsQuery } from "queries/useRegistryDetailsQuery"; +import { isUndefined } from "utils/index"; const Container = styled.div` display: flex; @@ -48,14 +50,21 @@ const StyledLink = styled(Link)<{ isActive: boolean }>` )}; `; -const links = [ - { to: "/", text: "Home" }, - { to: CURATION_POLICY, text: "Curation Policy" }, -]; - const Explore: React.FC = () => { const location = useLocation(); const { toggleIsOpen } = useOpenContext(); + const { data: mainCurate } = useRegistryDetailsQuery(MAIN_CURATE_ADDRESS); + + const links = useMemo( + () => [ + { to: "/", text: "Home" }, + { + to: isUndefined(mainCurate) ? "/" : `${IPFS_GATEWAY}${mainCurate.registry.policyURI}`, + text: "Curation Policy", + }, + ], + [mainCurate] + ); return ( diff --git a/web/src/pages/AllLists/RegistriesFetcher.tsx b/web/src/pages/AllLists/RegistriesFetcher.tsx index 32d02b9..c05932f 100644 --- a/web/src/pages/AllLists/RegistriesFetcher.tsx +++ b/web/src/pages/AllLists/RegistriesFetcher.tsx @@ -4,8 +4,6 @@ import { useWindowSize } from "react-use"; import { useListRootPath, decodeListURIFilter } from "utils/uri"; import RegistriesDisplay from "components/RegistriesDisplay"; import { BREAKPOINT_LANDSCAPE } from "styles/landscapeStyle"; -import { DEFAULT_CHAIN } from "consts/chains"; -import { listOfListsAddresses } from "utils/listOfListsAddresses"; import { useItemsQuery } from "queries/useItemsQuery"; import { useRegistriesByIdsQuery } from "queries/useRegistriesByIdsQuery"; import { isUndefined } from "utils/index"; @@ -13,6 +11,7 @@ import { OrderDirection } from "src/graphql/graphql"; import { useRegistryDetailsQuery } from "hooks/queries/useRegistryDetailsQuery"; import { List_filters } from "consts/filters"; import { sortRegistriesByIds } from "utils/sortRegistriesByIds"; +import { MAIN_CURATE_ADDRESS } from "src/consts"; const RegistriesFetcher: React.FC = () => { const { page, order, filter } = useParams(); @@ -28,14 +27,14 @@ const RegistriesFetcher: React.FC = () => { const registrySkip = registriesPerPage * (pageNumber - 1); const decodedFilter = decodeListURIFilter(filter ?? "all"); - const { data: mainCurate } = useRegistryDetailsQuery(listOfListsAddresses[DEFAULT_CHAIN]); + const { data: mainCurate } = useRegistryDetailsQuery(MAIN_CURATE_ADDRESS); // get items from the main curate as these are the registries const { data: itemsData, isLoading: isItemDataLoading } = useItemsQuery( registrySkip, registriesPerPage, { - registry: listOfListsAddresses[DEFAULT_CHAIN], + registry: MAIN_CURATE_ADDRESS, ...decodedFilter, }, order === "asc" ? OrderDirection.Asc : OrderDirection.Desc, diff --git a/web/src/pages/Home/Highlights/index.tsx b/web/src/pages/Home/Highlights/index.tsx index 92d1734..4692cda 100644 --- a/web/src/pages/Home/Highlights/index.tsx +++ b/web/src/pages/Home/Highlights/index.tsx @@ -4,9 +4,7 @@ import { Button } from "@kleros/ui-components-library"; import Header from "./Header"; import RegistryCard from "components/RegistryCard"; import { SkeletonRegistryCard } from "components/StyledSkeleton"; -import { DEFAULT_CHAIN } from "consts/chains"; import { isUndefined } from "utils/index"; -import { listOfListsAddresses } from "utils/listOfListsAddresses"; import { useNavigateAndScrollTop } from "hooks/useNavigateAndScrollTop"; import { useItemsQuery } from "queries/useItemsQuery"; import { useRegistriesByIdsQuery } from "queries/useRegistriesByIdsQuery"; @@ -15,6 +13,7 @@ import { sortRegistriesByIds } from "utils/sortRegistriesByIds"; import { Status } from "src/graphql/graphql"; import { List_filters } from "consts/filters"; import { encodeListURIFilter } from "utils/uri"; +import { MAIN_CURATE_ADDRESS } from "src/consts"; const Container = styled.div` width: 100%; @@ -40,7 +39,7 @@ const HighlightedLists = () => { const navigateAndScrollTop = useNavigateAndScrollTop(); const { data: itemsData, isLoading: isItemsDataLoading } = useItemsQuery(0, 6, { - registry: listOfListsAddresses[DEFAULT_CHAIN], + registry: MAIN_CURATE_ADDRESS, ...List_filters.Active, }); @@ -58,7 +57,7 @@ const HighlightedLists = () => { const sortedRegstries = useMemo( () => (registriesData?.registries ? sortRegistriesByIds(registryIds, registriesData?.registries) : []), - [registriesData] + [registriesData, registryIds] ); const combinedListsData = useMemo(() => { diff --git a/web/src/pages/SubmitList/AdvancedParameters/index.tsx b/web/src/pages/SubmitList/AdvancedParameters/index.tsx index 5bb9f42..90d7584 100644 --- a/web/src/pages/SubmitList/AdvancedParameters/index.tsx +++ b/web/src/pages/SubmitList/AdvancedParameters/index.tsx @@ -84,9 +84,7 @@ const AdvancedParameters: React.FC = () => {
- - By default, the recommended parameters are selected. You can edit them or skip them by clicking on Next. - + By default, the recommended parameters are selected. You can edit them. {" "} theme.whiteBackground}; } `; @@ -76,7 +75,7 @@ const SubmitListButton: React.FC = () => { const { writeAsync: submit } = useCurateFactoryDeploy(config); const { writeAsync: submitListToCurate } = useCurateV2AddItem({ - address: listOfListsAddresses[DEFAULT_CHAIN], + address: MAIN_CURATE_ADDRESS, }); // calculate total cost to submit the list to Curate @@ -134,7 +133,7 @@ const SubmitListButton: React.FC = () => { setProgress(ListProgress.SubmitSuccess); const submittedListId = retrieveSubmittedListId(res.result.logs[0]); - setSubmittedListItemId(`${deployedAddress}-${submittedListId}@${listOfListsAddresses[DEFAULT_CHAIN]}`); + setSubmittedListItemId(`${deployedAddress}-${submittedListId}@${MAIN_CURATE_ADDRESS}`); resetListData(); } else { diff --git a/web/src/utils/listOfListsAddresses.ts b/web/src/utils/listOfListsAddresses.ts deleted file mode 100644 index 9d1e475..0000000 --- a/web/src/utils/listOfListsAddresses.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const listOfListsAddresses = { - "421614": "0xad0a109cc2bf4da3a9c505155e15e8c05bd95183", - "42161": "to be deployed", -}; diff --git a/web/src/utils/submitListUtils.ts b/web/src/utils/submitListUtils.ts index db99267..f28969e 100644 --- a/web/src/utils/submitListUtils.ts +++ b/web/src/utils/submitListUtils.ts @@ -5,6 +5,8 @@ import { isUndefined } from "."; import { KLEROS_ARBITRATOR, TEMPLATE_REGISTRY } from "consts/arbitration"; import { ItemDetailsFragment, Status } from "src/graphql/graphql"; import { arbitrum } from "viem/chains"; +import { netlifyUri } from "src/generatedNetlifyInfo.json"; +import { DEFAULT_CHAIN } from "consts/chains"; export const constructListParams = (listData: IListData, listMetadata: IListMetadata) => { const baseTemplate = { ...listData } as IList; @@ -107,8 +109,9 @@ const constructRegistrationTemplate = (listMetadata: IListMetadata) => { category: "Curated Lists", policyURI: listMetadata.policyURI, - frontendUrl: window.origin, - arbitratorChainID: "421614", + frontendUrl: `${netlifyUri}/#/lists/item/{{ itemID }}@{{listAddress}}`, + //TODO : this will depend on the chain the dispute is created on? + arbitratorChainID: DEFAULT_CHAIN, arbitratorAddress: KLEROS_ARBITRATOR, }); }; @@ -149,8 +152,8 @@ const constructRemovalTemplate = (listMetadata: IListMetadata) => { category: "Curated Lists", policyURI: listMetadata.policyURI, - frontendUrl: window.origin, - arbitratorChainID: "421614", + frontendUrl: `${netlifyUri}/#/lists/item/{{ itemID }}@{{listAddress}}`, + arbitratorChainID: DEFAULT_CHAIN, arbitratorAddress: KLEROS_ARBITRATOR, }); }; diff --git a/web/wagmi.config.ts b/web/wagmi.config.ts index d70a3c4..ea60031 100644 --- a/web/wagmi.config.ts +++ b/web/wagmi.config.ts @@ -33,6 +33,28 @@ const readArtifacts = async (viemChainName: string, hardhatChainName?: string) = }); } } + + // read external contracts, Ex :- KlerosCore, EvidenceModule + const externalContractsdirectoryPath = `../node_modules/@kleros/kleros-v2-contracts/deployments/${ + hardhatChainName ?? viemChainName + }`; + const externalfiles = await readdir(externalContractsdirectoryPath); + for (const file of externalfiles) { + const { name, ext } = parse(file); + if (ext === ".json") { + const filePath = join(externalContractsdirectoryPath, file); + const fileContent = await readFile(filePath, "utf-8"); + const jsonContent = JSON.parse(fileContent); + results.push({ + name, + address: { + [chain.id]: jsonContent.address as `0x{string}`, + }, + abi: jsonContent.abi, + }); + } + } + return results; }; diff --git a/yarn.lock b/yarn.lock index 12bd8e8..baab5eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4790,6 +4790,7 @@ __metadata: "@filebase/client": "npm:^0.0.5" "@graphql-codegen/cli": "npm:^4.0.1" "@graphql-codegen/client-preset": "npm:^4.2.0" + "@kleros/kleros-v2-contracts": "npm:^0.3.2" "@kleros/ui-components-library": "npm:^2.12.0" "@middy/core": "npm:^5.3.5" "@middy/http-json-body-parser": "npm:^5.3.5"