Skip to content

Commit 2162e56

Browse files
alcercujaybuidl
authored andcommitted
feat(wip/web): migrate contract interactions to wagmi
1 parent 341d0e5 commit 2162e56

File tree

7 files changed

+126
-81
lines changed

7 files changed

+126
-81
lines changed

web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import React, { useState } from "react";
22
import styled from "styled-components";
33
import { useParams } from "react-router-dom";
44
import { useAccount, useBalance } from "wagmi";
5+
import { useDebounce } from "react-use";
56
import { Field, Button } from "@kleros/ui-components-library";
6-
import { DisputeKitClassic } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/dispute-kits/DisputeKitClassic";
7-
import { useConnectedContract } from "hooks/useConnectedContract";
7+
import {
8+
usePrepareDisputeKitClassicFundAppeal,
9+
useDisputeKitClassicFundAppeal,
10+
} from "hooks/contracts/generated";
811
import { wrapWithToast } from "utils/wrapWithToast";
912
import { useParsedAmount } from "hooks/useParsedAmount";
1013
import {
@@ -13,6 +16,7 @@ import {
1316
useFundingContext,
1417
} from "hooks/useClassicAppealContext";
1518
import { notUndefined } from "utils/index";
19+
import { BigNumber } from "ethers";
1620

1721
const Fund: React.FC = () => {
1822
const loserSideCountdown = useLoserSideCountdownContext();
@@ -26,15 +30,22 @@ const Fund: React.FC = () => {
2630
const { data: balance } = useBalance({
2731
address,
2832
watch: true,
29-
cacheTime: 12_000,
3033
});
3134
const [amount, setAmount] = useState("");
32-
const parsedAmount = useParsedAmount(amount);
35+
const [debouncedAmount, setDebouncedAmount] = useState("");
36+
useDebounce(() => setDebouncedAmount(amount), 500, [amount]);
37+
const parsedAmount = useParsedAmount(debouncedAmount);
3338
const [isSending, setIsSending] = useState(false);
34-
const disputeKitClassic = useConnectedContract(
35-
"DisputeKitClassic"
36-
) as DisputeKitClassic;
3739
const { selectedOption } = useSelectedOptionContext();
40+
const { config: fundAppealConfig } = usePrepareDisputeKitClassicFundAppeal({
41+
enabled: notUndefined([id, selectedOption]),
42+
args: [BigNumber.from(id), BigNumber.from(selectedOption)],
43+
overrides: {
44+
value: parsedAmount,
45+
},
46+
});
47+
const { writeAsync: fundAppeal } =
48+
useDisputeKitClassicFundAppeal(fundAppealConfig);
3849
return needFund ? (
3950
<div>
4051
<label>How much ETH do you want to contribute?</label>
@@ -54,18 +65,11 @@ const Fund: React.FC = () => {
5465
!balance ||
5566
parsedAmount.gt(balance.value)
5667
}
57-
text={typeof balance === "undefined" ? "Connect to Fund" : "Fund"}
68+
text={isDisconnected ? "Connect to Fund" : "Fund"}
5869
onClick={() => {
59-
if (
60-
typeof selectedOption !== "undefined" &&
61-
typeof id !== "undefined"
62-
) {
70+
if (fundAppeal) {
6371
setIsSending(true);
64-
wrapWithToast(
65-
disputeKitClassic.fundAppeal(id, selectedOption, {
66-
value: parsedAmount,
67-
})
68-
)
72+
wrapWithToast(fundAppeal!())
6973
.then(() => {
7074
setAmount("");
7175
close();

web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import React, { useState } from "react";
22
import styled from "styled-components";
3+
import { BigNumber } from "ethers";
4+
import { useSigner } from "wagmi";
5+
import { toast } from "react-toastify";
36
import Modal from "react-modal";
47
import { Textarea, Button } from "@kleros/ui-components-library";
5-
import { DisputeKitClassic } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/dispute-kits/DisputeKitClassic";
6-
import { wrapWithToast } from "utils/wrapWithToast";
7-
import { useConnectedContract } from "hooks/useConnectedContract";
8+
import { useDisputeKitClassic } from "hooks/contracts/generated";
9+
import { wrapWithToast, OPTIONS as toastOptions } from "utils/wrapWithToast";
810
import { uploadFormDataToIPFS } from "utils/uploadFormDataToIPFS";
911

1012
const SubmitEvidenceModal: React.FC<{
1113
isOpen: boolean;
1214
evidenceGroup: string;
1315
close: () => void;
1416
}> = ({ isOpen, evidenceGroup, close }) => {
15-
const disputeKit = useConnectedContract(
16-
"DisputeKitClassic"
17-
) as DisputeKitClassic;
17+
const { data: signer } = useSigner();
18+
const disputeKit = useDisputeKitClassic({
19+
signerOrProvider: signer,
20+
});
1821
const [isSending, setIsSending] = useState(false);
1922
const [message, setMessage] = useState("");
2023
return (
@@ -37,23 +40,29 @@ const SubmitEvidenceModal: React.FC<{
3740
isLoading={isSending}
3841
disabled={isSending}
3942
onClick={() => {
40-
setIsSending(true);
41-
const formData = constructEvidence(message);
42-
uploadFormDataToIPFS(formData)
43-
.then(async (res) => {
44-
const response = await res.json();
45-
if (res.status === 200) {
46-
const cid = "/ipfs/" + response["cid"];
47-
await wrapWithToast(
48-
disputeKit.submitEvidence(evidenceGroup, cid)
49-
).then(() => {
50-
setMessage("");
51-
close();
52-
});
53-
}
54-
})
55-
.catch()
56-
.finally(() => setIsSending(false));
43+
if (disputeKit) {
44+
setIsSending(true);
45+
const formData = constructEvidence(message);
46+
toast.info("Uploading to IPFS", toastOptions);
47+
uploadFormDataToIPFS(formData)
48+
.then(async (res) => {
49+
const response = await res.json();
50+
if (res.status === 200) {
51+
const cid = "/ipfs/" + response["cid"];
52+
await wrapWithToast(
53+
disputeKit.submitEvidence(
54+
BigNumber.from(evidenceGroup),
55+
cid
56+
)
57+
).then(() => {
58+
setMessage("");
59+
close();
60+
});
61+
}
62+
})
63+
.catch()
64+
.finally(() => setIsSending(false));
65+
}
5766
}}
5867
/>
5968
</ButtonArea>

web/src/pages/Cases/CaseDetails/Voting/Binary.tsx

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
1-
import React, { useState } from "react";
1+
import React, { useMemo, useState } from "react";
22
import styled from "styled-components";
33
import { useParams } from "react-router-dom";
4-
import { DisputeKitClassic } from "@kleros/kleros-v2-contracts/typechain-types/src/arbitration/dispute-kits/DisputeKitClassic";
54
import { Button, Textarea } from "@kleros/ui-components-library";
6-
import { useConnectedContract } from "hooks/useConnectedContract";
5+
import { useDisputeKitClassic } from "hooks/contracts/generated";
76
import { useGetMetaEvidence } from "queries/useGetMetaEvidence";
87
import { wrapWithToast } from "utils/wrapWithToast";
8+
import { useSigner } from "wagmi";
9+
import { BigNumber } from "ethers";
910

1011
const Binary: React.FC<{ arbitrable?: string; voteIDs: string[] }> = ({
1112
arbitrable,
1213
voteIDs,
1314
}) => {
1415
const { id } = useParams();
16+
const parsedDisputeID = BigNumber.from(id);
17+
const parsedVoteIDs = useMemo(
18+
() => voteIDs.map((voteID) => BigNumber.from(voteID)),
19+
[voteIDs]
20+
);
1521
const { data: metaEvidence } = useGetMetaEvidence(id, arbitrable);
1622
const [chosenOption, setChosenOption] = useState(-1);
1723
const [isSending, setIsSending] = useState(false);
1824
const [justification, setJustification] = useState("");
19-
const disputeKit = useConnectedContract(
20-
"DisputeKitClassic"
21-
) as DisputeKitClassic;
25+
const { data: signer } = useSigner();
26+
const disputeKit = useDisputeKitClassic({
27+
signerOrProvider: signer,
28+
});
2229
return id ? (
2330
<Container>
2431
<MainContainer>
@@ -42,14 +49,22 @@ const Binary: React.FC<{ arbitrable?: string; voteIDs: string[] }> = ({
4249
disabled={isSending}
4350
isLoading={chosenOption === i + 1}
4451
onClick={() => {
45-
setIsSending(true);
46-
setChosenOption(i + 1);
47-
wrapWithToast(
48-
disputeKit.castVote(id, voteIDs, i + 1, 0, justification)
49-
).finally(() => {
50-
setChosenOption(-1);
51-
setIsSending(false);
52-
});
52+
if (disputeKit) {
53+
setIsSending(true);
54+
setChosenOption(i + 1);
55+
wrapWithToast(
56+
disputeKit!.castVote(
57+
parsedDisputeID,
58+
parsedVoteIDs,
59+
BigNumber.from(i + 1),
60+
BigNumber.from(0),
61+
justification
62+
)
63+
).finally(() => {
64+
setChosenOption(-1);
65+
setIsSending(false);
66+
});
67+
}
5368
}}
5469
/>
5570
)
@@ -63,14 +78,22 @@ const Binary: React.FC<{ arbitrable?: string; voteIDs: string[] }> = ({
6378
disabled={isSending}
6479
isLoading={chosenOption === 0}
6580
onClick={() => {
66-
setIsSending(true);
67-
setChosenOption(0);
68-
wrapWithToast(
69-
disputeKit.castVote(id, voteIDs, 0, 0, justification)
70-
).finally(() => {
71-
setChosenOption(-1);
72-
setIsSending(false);
73-
});
81+
if (disputeKit) {
82+
setIsSending(true);
83+
setChosenOption(0);
84+
wrapWithToast(
85+
disputeKit.castVote(
86+
parsedDisputeID,
87+
parsedVoteIDs,
88+
BigNumber.from(0),
89+
BigNumber.from(0),
90+
justification
91+
)
92+
).finally(() => {
93+
setChosenOption(-1);
94+
setIsSending(false);
95+
});
96+
}
7497
}}
7598
/>
7699
</RefuseToArbitrateContainer>

web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useState } from "react";
22
import styled from "styled-components";
33
import { useParams } from "react-router-dom";
44
import { utils } from "ethers";
5+
import { useDebounce } from "react-use";
56
import { useAccount } from "wagmi";
67
import { Button, Field } from "@kleros/ui-components-library";
78

@@ -22,7 +23,9 @@ const InputDisplay: React.FC<IInputDisplay> = ({
2223
setIsSending,
2324
}) => {
2425
const [amount, setAmount] = useState("");
25-
const parsedAmount = useParsedAmount(amount);
26+
const [debouncedAmount, setDebouncedAmount] = useState("");
27+
useDebounce(() => setDebouncedAmount(amount), 500, [amount]);
28+
const parsedAmount = useParsedAmount(debouncedAmount);
2629

2730
const { id } = useParams();
2831
const { address } = useAccount();
@@ -55,7 +58,7 @@ const InputDisplay: React.FC<IInputDisplay> = ({
5558
placeholder={isStaking ? "Amount to stake" : "Amount to withdraw"}
5659
message={
5760
isStaking
58-
? "You need two transactions, one to increase allowance, the other to stake."
61+
? "You may need two transactions, one to increase allowance, the other to stake."
5962
: undefined
6063
}
6164
variant="info"
@@ -77,8 +80,6 @@ const InputDisplay: React.FC<IInputDisplay> = ({
7780
</>
7881
);
7982
};
80-
// onClick={activate}
81-
// disabled={connecting}
8283

8384
export default InputDisplay;
8485

web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import React, { useMemo } from "react";
22
import { useParams } from "react-router-dom";
33
import { BigNumber } from "ethers";
4-
import { Button } from "@kleros/ui-components-library";
54
import { useAccount } from "wagmi";
6-
5+
import { Button } from "@kleros/ui-components-library";
6+
import { usePNKAllowance } from "hooks/queries/usePNKAllowance";
77
import {
88
useKlerosCore,
99
useKlerosCoreSetStake,
1010
usePrepareKlerosCoreSetStake,
11-
usePnkAllowance,
11+
usePnkBalanceOf,
1212
usePnkIncreaseAllowance,
1313
usePreparePnkIncreaseAllowance,
1414
} from "hooks/contracts/generated";
15-
16-
import { usePNKBalance } from "queries/usePNKBalance";
1715
import { useJurorBalance } from "queries/useJurorBalance";
1816
import { wrapWithToast } from "utils/wrapWithToast";
1917
import { notUndefined } from "utils/index";
@@ -41,20 +39,19 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({
4139
}) => {
4240
const { id } = useParams();
4341
const { address } = useAccount();
44-
const { data: balance } = usePNKBalance(address);
45-
const { data: jurorBalance } = useJurorBalance(address, id);
46-
const { data: allowance } = usePnkAllowance({
42+
const { data: balance } = usePnkBalanceOf({
4743
enabled: notUndefined(address),
4844
args: [address!],
4945
watch: true,
50-
cacheOnBlock: true,
5146
});
47+
const { data: jurorBalance } = useJurorBalance(address, id);
48+
const { data: allowance } = usePNKAllowance(address);
5249

5350
const isStaking = action === ActionType.stake;
5451
const isAllowance = isStaking && allowance && allowance.lt(parsedAmount);
5552

5653
const targetStake = useMemo(() => {
57-
if (action === ActionType.stake || action === ActionType.allowance) {
54+
if (action === ActionType.stake) {
5855
return jurorBalance?.staked.add(parsedAmount);
5956
} else {
6057
return jurorBalance?.staked.sub(parsedAmount);
@@ -64,7 +61,10 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({
6461
const klerosCore = useKlerosCore();
6562
const { config: increaseAllowanceConfig } = usePreparePnkIncreaseAllowance({
6663
enabled: notUndefined([klerosCore, targetStake, allowance]),
67-
args: [klerosCore!.address, targetStake!.sub(allowance!)],
64+
args: [
65+
klerosCore?.address,
66+
targetStake?.sub(allowance ?? BigNumber.from(0))!,
67+
],
6868
});
6969
const { writeAsync: increaseAllowance } = usePnkIncreaseAllowance(
7070
increaseAllowanceConfig
@@ -79,8 +79,8 @@ const StakeWithdrawButton: React.FC<IActionButton> = ({
7979
};
8080

8181
const { config: setStakeConfig } = usePrepareKlerosCoreSetStake({
82-
enabled: notUndefined(targetStake),
83-
args: [targetStake!, targetStake!],
82+
enabled: notUndefined([targetStake, id]),
83+
args: [id, targetStake],
8484
});
8585
const { writeAsync: setStake } = useKlerosCoreSetStake(setStakeConfig);
8686
const handleStake = () => {

web/src/utils/wrapWithToast.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export const OPTIONS = {
1414
export async function wrapWithToast(tx: Promise<any>) {
1515
toast.info("Transaction initiated", OPTIONS);
1616
await tx
17-
.then((tx) => {
18-
tx.wait(2);
17+
.then(async (tx) => {
18+
await tx.wait(2);
1919
toast.success("Transaction mined!", OPTIONS);
2020
})
2121
.catch((error) => {

web/wagmi.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { react } from "@wagmi/cli/plugins";
33
import { arbitrumGoerli } from "wagmi/chains";
44
import KlerosCore from "@kleros/kleros-v2-contracts/deployments/arbitrumGoerli/KlerosCore.json" assert { type: "json" };
55
import PNK from "@kleros/kleros-v2-contracts/deployments/arbitrumGoerli/PNK.json" assert { type: "json" };
6+
import DisputeKitClassic from "@kleros/kleros-v2-contracts/deployments/arbitrumGoerli/DisputeKitClassic.json" assert { type: "json" };
67

78
export default defineConfig({
89
out: "src/hooks/contracts/generated.ts",
@@ -14,6 +15,13 @@ export default defineConfig({
1415
},
1516
abi: KlerosCore.abi,
1617
},
18+
{
19+
name: "DisputeKitClassic",
20+
address: {
21+
[arbitrumGoerli.id]: DisputeKitClassic.address,
22+
},
23+
abi: DisputeKitClassic.abi,
24+
},
1725
{
1826
name: "PNK",
1927
address: {

0 commit comments

Comments
 (0)