Skip to content

Commit 5a81f9e

Browse files
committed
feat: dispute kit helper
1 parent 4594536 commit 5a81f9e

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { getContracts } from "./contractsViem";
2+
import { Abi, AbiEvent, getAbiItem, PublicClient } from "viem";
3+
import { DeploymentName } from "./utils";
4+
5+
export type DisputeKitContracts = ReturnType<typeof getContracts>;
6+
export type DisputeKit =
7+
| NonNullable<DisputeKitContracts["disputeKitClassic"]>
8+
| NonNullable<DisputeKitContracts["disputeKitShutter"]>
9+
| NonNullable<DisputeKitContracts["disputeKitGated"]>
10+
| NonNullable<DisputeKitContracts["disputeKitGatedShutter"]>
11+
| null;
12+
export type DisputeKitInfos = {
13+
address: `0x${string}`;
14+
contract: DisputeKit;
15+
isGated: boolean;
16+
isShutter: boolean;
17+
};
18+
export type DisputeKitByIds = Record<string, DisputeKitInfos>;
19+
20+
const fetchDisputeKits = async (client: PublicClient, klerosCoreAddress: `0x${string}`, klerosCoreAbi: Abi) => {
21+
const DisputeKitCreated = getAbiItem({
22+
abi: klerosCoreAbi,
23+
name: "DisputeKitCreated",
24+
}) as AbiEvent;
25+
const logs = await client.getLogs({
26+
address: klerosCoreAddress,
27+
event: DisputeKitCreated,
28+
fromBlock: 0n,
29+
toBlock: "latest",
30+
});
31+
return Object.fromEntries(
32+
logs
33+
.filter((log) => {
34+
const args = log.args as Record<string, unknown>;
35+
return "_disputeKitID" in args && "_disputeKitAddress" in args;
36+
})
37+
.map((log) => {
38+
const { _disputeKitID, _disputeKitAddress } = log.args as {
39+
_disputeKitID: bigint;
40+
_disputeKitAddress: string;
41+
};
42+
return {
43+
disputeKitID: _disputeKitID,
44+
disputeKitAddress: _disputeKitAddress,
45+
};
46+
})
47+
.map(({ disputeKitID, disputeKitAddress }) => [disputeKitID!.toString(), disputeKitAddress as `0x${string}`])
48+
);
49+
};
50+
51+
export const getDisputeKits = async (client: PublicClient, deployment: DeploymentName): Promise<DisputeKitByIds> => {
52+
const { klerosCore, disputeKitClassic, disputeKitShutter, disputeKitGated, disputeKitGatedShutter } = getContracts({
53+
publicClient: client,
54+
deployment: deployment,
55+
});
56+
57+
const isDefined = <T>(kit: T): kit is NonNullable<T> => kit != null;
58+
const disputeKitContracts = [disputeKitClassic, disputeKitShutter, disputeKitGated, disputeKitGatedShutter].filter(
59+
isDefined
60+
);
61+
const shutterEnabled = [disputeKitShutter, disputeKitGatedShutter].filter(isDefined);
62+
const gatedEnabled = [disputeKitGated, disputeKitGatedShutter].filter(isDefined);
63+
64+
const disputeKitMap = await fetchDisputeKits(client, klerosCore.address, klerosCore.abi);
65+
66+
return Object.fromEntries(
67+
Object.entries(disputeKitMap).map(([disputeKitID, address]) => {
68+
const contract =
69+
disputeKitContracts.find((contract) => contract.address.toLowerCase() === address.toLowerCase()) ?? null;
70+
return [
71+
disputeKitID,
72+
{
73+
address,
74+
contract: contract satisfies DisputeKit,
75+
isGated: contract
76+
? gatedEnabled.some((gated) => contract.address.toLowerCase() === gated.address.toLowerCase())
77+
: false,
78+
isShutter: contract
79+
? shutterEnabled.some((shutter) => contract.address.toLowerCase() === shutter.address.toLowerCase())
80+
: false,
81+
},
82+
];
83+
})
84+
);
85+
};

contracts/deployments/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ export * from "./utils";
1717
// Contracts getters
1818
export { getContracts as getContractsEthers } from "./contractsEthers";
1919
export { getContracts as getContractsViem } from "./contractsViem";
20+
21+
// Dispute kits getters
22+
export { getDisputeKits as getDisputeKitsViem, type DisputeKitByIds, type DisputeKitInfos } from "./disputeKitsViem";
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { getDisputeKits } from "../deployments/disputeKitsViem";
2+
import { createPublicClient, http } from "viem";
3+
import { arbitrumSepolia } from "viem/chains";
4+
5+
const rpc = process.env.ARBITRUM_SEPOLIA_RPC;
6+
if (!rpc) {
7+
throw new Error("ARBITRUM_SEPOLIA_RPC is not set");
8+
}
9+
10+
const client = createPublicClient({
11+
chain: arbitrumSepolia,
12+
transport: http(rpc),
13+
});
14+
15+
async function main() {
16+
try {
17+
console.log("Fetching DisputeKitCreated events...");
18+
const disputeKitResult = await getDisputeKits(client, "devnet");
19+
console.log(disputeKitResult);
20+
} catch (error) {
21+
console.error("Error fetching events:", error);
22+
throw error;
23+
}
24+
}
25+
26+
if (require.main === module) {
27+
main()
28+
.then(() => process.exit(0))
29+
.catch((error) => {
30+
console.error(error);
31+
process.exit(1);
32+
});
33+
}

0 commit comments

Comments
 (0)