Skip to content

Commit 9d53d70

Browse files
committed
fix: coderabbit and other type fixes
1 parent 65a466a commit 9d53d70

13 files changed

+122
-36
lines changed

cspell.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"softwareTerms"
1010
],
1111
"words": [
12+
"Arbitrables",
1213
"arbitrum",
1314
"ARBMAINNET",
1415
"ARBSEPOLIA",

kleros-sdk/src/dataMappings/actions/fetchIpfsJsonAction.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const fetchIpfsJsonAction = async (mapping: FetchIpfsJsonMapping) => {
1818

1919
const response = await fetch(httpUri, { method: "GET" });
2020

21-
if (!response) {
21+
if (!response.ok) {
2222
throw new Error("Failed to fetch data from IPFS");
2323
}
2424

web-devtools/next.config.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const nextConfig = {
1313
webpack(config) {
1414
// Grab the existing rule that handles SVG imports
1515
const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.(".svg"));
16+
if (!fileLoaderRule) {
17+
throw new Error("Could not find the existing SVG rule to modify.");
18+
}
1619

1720
config.module.rules.push(
1821
// Reapply the existing rule, but only for svg imports ending in ?url

web-devtools/src/components/LabeledInput.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from "react";
1+
import React, { useLayoutEffect, useRef, useState } from "react";
22
import styled, { css } from "styled-components";
33

44
import { Checkbox, Field, type CheckboxProps, type FieldProps } from "@kleros/ui-components-library";
@@ -88,13 +88,19 @@ type LabeledInputProps = BaseProps & (CheckboxInputProps | DefaultInputProps);
8888

8989
const LabeledInput: React.FC<LabeledInputProps> = ({ inputType = "field", label, ...props }) => {
9090
const labelRef = useRef<HTMLDivElement>(null);
91+
const [labelWidth, setLabelWidth] = useState(0);
92+
useLayoutEffect(() => {
93+
if (labelRef.current) {
94+
setLabelWidth(labelRef.current.offsetWidth);
95+
}
96+
}, []);
9197
return (
9298
<Container>
9399
<LabelContainer ref={labelRef} isField={inputType === "field"}>
94100
<Label>{label}</Label>
95101
</LabelContainer>
96102
<InputContainer isField={inputType === "field"}>
97-
{inputType === "field" && <StyledField {...props} paddingLeft={labelRef.current?.offsetWidth} />}
103+
{inputType === "field" && <StyledField {...props} paddingLeft={labelWidth} />}
98104
{inputType === "checkbox" && <StyledCheckbox label="&nbsp;" {...props} />}
99105
</InputContainer>
100106
</Container>

web-devtools/src/components/ReactMarkdown.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ const StyledMarkdown = styled(Reactmkdwn)`
77
font-size: 16px;
88
`;
99

10-
const ReactMarkdown: React.FC<{ children: string }> = ({ children }) => <StyledMarkdown>{children}</StyledMarkdown>;
10+
const ReactMarkdown: React.FC<{ children: string }> = ({ children }) => {
11+
if (!children) {
12+
return <div>No content available</div>;
13+
}
14+
try {
15+
return <StyledMarkdown>{children}</StyledMarkdown>;
16+
} catch (error) {
17+
return <div>Error rendering content</div>;
18+
}
19+
};
1120

1221
export default ReactMarkdown;

web-devtools/src/consts/arbitratorTypes.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export enum ArbitratorTypes {
44
neo,
55
}
66

7-
export const getArbitratorType = (id: keyof typeof ArbitratorTypes = "vanilla"): ArbitratorTypes => ArbitratorTypes[id];
7+
export const getArbitratorType = (id: keyof typeof ArbitratorTypes = "vanilla" as const): ArbitratorTypes =>
8+
ArbitratorTypes[id];

web-devtools/src/context/GraphqlBatcher.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const fetcher = async (queries: IQuery[]) => {
2727
try {
2828
return request(url, document, variables).then((result) => ({ id, result }));
2929
} catch (error) {
30-
console.error("Graph error: ", { error });
30+
console.error("Graph error: ", { error, query: { id, document, variables, isDisputeTemplate, chainId } });
3131
debounceErrorToast("Graph query error: failed to fetch data.");
3232
return { id, result: {} };
3333
}

web-devtools/src/context/RulerContext.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ const RulerContextProvider: React.FC<{ children: React.ReactNode }> = ({ childre
4949

5050
useEffect(() => {
5151
if (!arbitrableSettingsData) return;
52+
const [rulingMode, rulingRaw, tied, overridden] = arbitrableSettingsData;
5253
setArbitrableSettings({
53-
rulingMode: arbitrableSettingsData[0],
54-
ruling: Number(arbitrableSettingsData[1]),
55-
tied: arbitrableSettingsData[2],
56-
overridden: arbitrableSettingsData[3],
54+
rulingMode,
55+
ruling: Number(rulingRaw),
56+
tied,
57+
overridden,
5758
});
5859
}, [arbitrableSettingsData]);
5960

@@ -62,7 +63,7 @@ const RulerContextProvider: React.FC<{ children: React.ReactNode }> = ({ childre
6263
return;
6364

6465
setKnownArbitrables([...knownArbitrables, arbitrable?.toLowerCase()]);
65-
}, [arbitrable, knownArbitrables, setKnownArbitrables]);
66+
}, [arbitrable, knownArbitrables]);
6667

6768
const refetchData = useCallback(() => {
6869
refetchArbitrableSettings();
@@ -80,7 +81,7 @@ const RulerContextProvider: React.FC<{ children: React.ReactNode }> = ({ childre
8081
refetchData,
8182
knownArbitrables,
8283
}),
83-
[arbitrable, setArbitrable, arbitrableSettings, currentDeveloper, refetchData, knownArbitrables]
84+
[arbitrable, arbitrableSettings, currentDeveloper, refetchData, knownArbitrables]
8485
)}
8586
>
8687
{children}

web-devtools/src/context/Web3Provider.tsx

+25-8
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,38 @@ import React from "react";
33
import { createWeb3Modal } from "@web3modal/wagmi/react";
44
import { type Chain } from "viem";
55
import { createConfig, fallback, http, WagmiProvider, webSocket } from "wagmi";
6-
import { mainnet, arbitrumSepolia } from "wagmi/chains";
6+
import { mainnet, arbitrumSepolia, arbitrum, gnosisChiado, sepolia, gnosis } from "wagmi/chains";
77
import { walletConnect } from "wagmi/connectors";
88

99
import { ALL_CHAINS } from "consts/chains";
1010

1111
import { theme } from "styles/Theme";
1212

13-
const alchemyApiKey = process.env.NEXT_PUBLIC_ALCHEMY_API_KEY ?? "";
13+
const alchemyApiKey = process.env.NEXT_PUBLIC_ALCHEMY_API_KEY;
14+
if (!alchemyApiKey) {
15+
throw new Error("Alchemy API key is not set in NEXT_PUBLIC_ALCHEMY_API_KEY environment variable.");
16+
}
1417

15-
// https://github.com/alchemyplatform/alchemy-sdk-js/blob/96b3f62/src/types/types.ts#L98-L119
16-
const alchemyToViemChain = {
18+
// https://github.com/alchemyplatform/alchemy-sdk-js/blob/c4440cb/src/types/types.ts#L98-L153
19+
const alchemyToViemChain: Record<number, string> = {
1720
[arbitrumSepolia.id]: "arb-sepolia",
21+
[arbitrum.id]: "arb-mainnet",
1822
[mainnet.id]: "eth-mainnet",
23+
[sepolia.id]: "eth-sepolia",
24+
[gnosis.id]: "gnosis-mainnet",
25+
[gnosisChiado.id]: "gnosis-chiado",
1926
};
2027

2128
type AlchemyProtocol = "https" | "wss";
2229

23-
// https://github.com/alchemyplatform/alchemy-sdk-js/blob/96b3f62/src/util/const.ts#L16-L18
24-
const alchemyURL = (protocol: AlchemyProtocol, chainId: number) =>
25-
`${protocol}://${alchemyToViemChain[chainId]}.g.alchemy.com/v2/${alchemyApiKey}`;
30+
// https://github.com/alchemyplatform/alchemy-sdk-js/blob/c4440cb/src/util/const.ts#L16-L18
31+
function alchemyURL(protocol: AlchemyProtocol, chainId: number): string {
32+
const network = alchemyToViemChain[chainId];
33+
if (!network) {
34+
throw new Error(`Unsupported chain ID: ${chainId}`);
35+
}
36+
return `${protocol}://${network}.g.alchemy.com/v2/${alchemyApiKey}`;
37+
}
2638

2739
export const getTransports = () => {
2840
const alchemyTransport = (chain: Chain) =>
@@ -36,7 +48,12 @@ export const getTransports = () => {
3648

3749
const chains = ALL_CHAINS as [Chain, ...Chain[]];
3850
const transports = getTransports();
39-
const projectId = process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID ?? "";
51+
52+
const projectId = process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID;
53+
if (!projectId) {
54+
throw new Error("WalletConnect project ID is not set in NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID environment variable.");
55+
}
56+
4057
const wagmiConfig = createConfig({
4158
chains,
4259
transports,

web-devtools/src/hooks/queries/useDisputeTemplateFromId.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@ export const useDisputeTemplateFromId = (templateId?: string) => {
2525
queryKey: [`disputeTemplate${templateId}`],
2626
enabled: isEnabled,
2727
staleTime: Infinity,
28-
queryFn: async () =>
29-
await graphqlBatcher.fetch({
28+
queryFn: async () => {
29+
const response = await graphqlBatcher.fetch({
3030
id: crypto.randomUUID(),
3131
document: disputeTemplateQuery,
3232
variables: { id: templateId?.toString() },
3333
isDisputeTemplate: true,
34-
}),
34+
});
35+
if (!response || response.errors) {
36+
throw new Error("Failed to fetch dispute template: " + response?.errors?.[0]?.message);
37+
}
38+
return response.data;
39+
},
3540
});
3641
};

web-devtools/src/utils/getGraphqlUrl.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@ import { arbitrumSepolia, arbitrum } from "wagmi/chains";
22

33
import { DEFAULT_CHAIN } from "../consts/chains";
44

5-
export const getGraphqlUrl = (isDisputeTemplate = false, chainId: number = DEFAULT_CHAIN) => {
6-
const CHAINID_TO_DISPUTE_TEMPLATE_SUBGRAPH: { [key: number]: string } = {
7-
[arbitrumSepolia.id]:
8-
process.env.NEXT_PUBLIC_DRT_ARBSEPOLIA_SUBGRAPH ??
9-
"Environment variable NEXT_PUBLIC_DRT_ARBSEPOLIA_SUBGRAPH not set.",
10-
[arbitrum.id]:
11-
process.env.NEXT_PUBLIC_DRT_ARBMAINNET_SUBGRAPH ??
12-
"Environment variable NEXT_PUBLIC_DRT_ARBMAINNET_SUBGRAPH not set.",
5+
function assertEnvVar(key: string): string {
6+
const value = process.env[key];
7+
if (!value) {
8+
throw new Error(`${key} not set`);
9+
}
10+
return value;
11+
}
12+
13+
export function getGraphqlUrl(isDisputeTemplate = false, chainId: number = DEFAULT_CHAIN) {
14+
const coreSubgraphEnvVar = "NEXT_PUBLIC_CORE_SUBGRAPH";
15+
const drtArbSepoliaSubgraphEnvVar = "NEXT_PUBLIC_DRT_ARBSEPOLIA_SUBGRAPH";
16+
const drtArbMainnetSubgraphEnvVar = "NEXT_PUBLIC_DRT_ARBMAINNET_SUBGRAPH";
17+
18+
const chainIdToDrtSubgraph: { [key: number]: string } = {
19+
[arbitrumSepolia.id]: drtArbSepoliaSubgraphEnvVar,
20+
[arbitrum.id]: drtArbMainnetSubgraphEnvVar,
1321
};
14-
const coreUrl = process.env.NEXT_PUBLIC_CORE_SUBGRAPH ?? "Environment variables NEXT_PUBLIC_CORE_SUBGRAPH not set.";
15-
return isDisputeTemplate ? CHAINID_TO_DISPUTE_TEMPLATE_SUBGRAPH[chainId] : coreUrl;
16-
};
22+
23+
return assertEnvVar(isDisputeTemplate ? chainIdToDrtSubgraph[chainId] : coreSubgraphEnvVar);
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { PublicClient, isAddress } from "viem";
2+
import { normalize } from "viem/ens";
3+
4+
export const validateAddress = async (address: string, publicClient: PublicClient): Promise<boolean> => {
5+
try {
6+
if (isAddress(address)) return true;
7+
8+
const isValidEns = (await publicClient.getEnsAddress({ name: normalize(address) })) !== null;
9+
10+
return isValidEns;
11+
} catch {
12+
return false;
13+
}
14+
};

web-devtools/wagmi.config.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,24 @@ import { parse, join } from "path";
44
import { type Config, type ContractConfig, defineConfig } from "@wagmi/cli";
55
import { react, actions } from "@wagmi/cli/plugins";
66
import dotenv from "dotenv";
7-
import { Chain } from "viem";
7+
import { Abi, Chain } from "viem";
8+
9+
import IArbitrableV2 from "@kleros/kleros-v2-contracts/artifacts/src/arbitration/interfaces/IArbitrableV2.sol/IArbitrableV2.json" assert { type: "json" };
10+
import IHomeGateway from "@kleros/kleros-v2-contracts/artifacts/src/gateway/interfaces/IHomeGateway.sol/IHomeGateway.json" assert { type: "json" };
811

912
import { ArbitratorTypes, getArbitratorType } from "./src/consts/arbitratorTypes";
1013
import { arbitrum, arbitrumSepolia, gnosis, gnosisChiado, mainnet, sepolia } from "viem/chains";
1114

1215
dotenv.config();
1316

17+
type ArtifactPartial = {
18+
abi: Abi;
19+
};
20+
21+
const getAbi = (artifact: any) => {
22+
return (artifact as ArtifactPartial).abi;
23+
};
24+
1425
const readArtifacts = async (type: ArbitratorTypes, viemChainName: string, hardhatChainName?: string) => {
1526
const artifactSuffix =
1627
type === ArbitratorTypes.vanilla
@@ -95,7 +106,17 @@ const getConfig = async (): Promise<Config> => {
95106

96107
return {
97108
out: "src/hooks/contracts/generated.ts",
98-
contracts: [...deploymentContracts],
109+
contracts: [
110+
...deploymentContracts,
111+
{
112+
name: "IHomeGateway",
113+
abi: getAbi(IHomeGateway),
114+
},
115+
{
116+
name: "IArbitrableV2",
117+
abi: getAbi(IArbitrableV2),
118+
},
119+
],
99120
plugins: [react(), actions()],
100121
};
101122
};

0 commit comments

Comments
 (0)