Skip to content

Commit 6a14db0

Browse files
authored
Merge pull request #20 from privacy-scaling-explorations/feat/finalize-with-coordinator-service
feat: add finalise button
2 parents b81680d + 604ee51 commit 6a14db0

File tree

16 files changed

+414
-244
lines changed

16 files changed

+414
-244
lines changed

bun.lock

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"@layerzerolabs/lz-definitions": "^2.3.27",
99
"@layerzerolabs/lz-v2-utilities": "^2.3.27",
1010
"@layerzerolabs/scan-client": "^0.0.8",
11-
"@maci-protocol/domainobjs": "0.0.0-ci.2b67e0e",
12-
"@maci-protocol/sdk": "0.0.0-ci.2b67e0e",
11+
"@maci-protocol/domainobjs": "0.0.0-ci.2cc4cdc",
12+
"@maci-protocol/sdk": "0.0.0-ci.2cc4cdc",
1313
"@react-native-async-storage/async-storage": "^1.23.1",
1414
"@shazow/whatsabi": "0.11.0",
1515
"@tanstack/query-async-storage-persister": "^5.49.1",
@@ -312,15 +312,15 @@
312312

313313
"@lit/reactive-element": ["@lit/reactive-element@2.1.0", "", { "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0" } }, "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA=="],
314314

315-
"@maci-protocol/contracts": ["@maci-protocol/contracts@0.0.0-ci.2b67e0e", "", { "dependencies": { "@excubiae/contracts": "^0.11.0", "@maci-protocol/core": "0.0.0-ci.2b67e0e", "@maci-protocol/crypto": "0.0.0-ci.2b67e0e", "@maci-protocol/domainobjs": "0.0.0-ci.2b67e0e", "@nomicfoundation/hardhat-ethers": "^3.0.8", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@nomicfoundation/hardhat-verify": "^2.0.13", "@openzeppelin/contracts": "^5.3.0", "@openzeppelin/merkle-tree": "^1.0.8", "@pcd/util": "^0.9.0", "@zk-kit/imt.sol": "2.0.0-beta.12", "@zk-kit/lean-imt": "^2.2.3", "circomlibjs": "^0.1.7", "ethers": "^6.14.0", "hardhat": "^2.24.0", "lowdb": "^1.0.0", "snarkjs": "^0.7.5", "solady": "^0.1.18", "solidity-docgen": "^0.6.0-beta.36", "uuid": "^11.1.0" }, "bin": { "maci-contracts": "./build/ts/index.js" } }, "sha512-quj6oZvm+C8lR0Mrumbpoag87RoRtnofn+n1aNMgmgIOwJi7/zV7pSzWHlRH8YByf0A1z0ix5xwWU9QuIBA/eg=="],
315+
"@maci-protocol/contracts": ["@maci-protocol/contracts@0.0.0-ci.2cc4cdc", "", { "dependencies": { "@excubiae/contracts": "^0.11.0", "@maci-protocol/core": "0.0.0-ci.2cc4cdc", "@maci-protocol/crypto": "0.0.0-ci.2cc4cdc", "@maci-protocol/domainobjs": "0.0.0-ci.2cc4cdc", "@nomicfoundation/hardhat-ethers": "^3.0.8", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@nomicfoundation/hardhat-verify": "^2.0.13", "@openzeppelin/contracts": "^5.3.0", "@openzeppelin/merkle-tree": "^1.0.8", "@pcd/util": "^0.9.0", "@zk-kit/imt.sol": "2.0.0-beta.12", "@zk-kit/lean-imt": "^2.2.3", "circomlibjs": "^0.1.7", "ethers": "^6.14.0", "hardhat": "^2.24.0", "lowdb": "^1.0.0", "snarkjs": "^0.7.5", "solady": "^0.1.18", "solidity-docgen": "^0.6.0-beta.36", "uuid": "^11.1.0" }, "bin": { "maci-contracts": "./build/ts/index.js" } }, "sha512-mYbj0ufxKQp3vQtg/TUCQbeDj9syxCkii4AOfJCH2kx3BsBv5jXc7C13GcaTYwSktWRNpoOkNHBET/I4r8X2SA=="],
316316

317-
"@maci-protocol/core": ["@maci-protocol/core@0.0.0-ci.2b67e0e", "", { "dependencies": { "@maci-protocol/crypto": "0.0.0-ci.2b67e0e", "@maci-protocol/domainobjs": "0.0.0-ci.2b67e0e", "@zk-kit/lean-imt": "^2.2.3", "lodash": "^4.17.21" } }, "sha512-O1NRf0kqo1eEfHg7+fMo7ra100l4nrRI8O5W8QR0X4KhOAaT09wVB6G66vbCJxghgvncK3qViI8lk5VByTYW+g=="],
317+
"@maci-protocol/core": ["@maci-protocol/core@0.0.0-ci.2cc4cdc", "", { "dependencies": { "@maci-protocol/crypto": "0.0.0-ci.2cc4cdc", "@maci-protocol/domainobjs": "0.0.0-ci.2cc4cdc", "@zk-kit/lean-imt": "^2.2.3", "lodash": "^4.17.21" } }, "sha512-6gD1EvTXZonorHwV6ArL7xWidCiAd6wAwM3/X9wS7qL/cTjjJlaXtEfBRkZ6ESjle9jW8OEvCPAz7RCA/qfz3w=="],
318318

319-
"@maci-protocol/crypto": ["@maci-protocol/crypto@0.0.0-ci.2b67e0e", "", { "dependencies": { "@zk-kit/baby-jubjub": "^1.0.3", "@zk-kit/eddsa-poseidon": "^1.1.0", "@zk-kit/poseidon-cipher": "^0.3.2", "ethers": "^6.14.0" } }, "sha512-/Tu2wqENdvrRNiw4BgVNZVPiVvUjgVmgPKLqu8RMMgz3ZrOE1Uu39Mwch/dSOMNXqspPBHTBjaLGwZNir3Hh/Q=="],
319+
"@maci-protocol/crypto": ["@maci-protocol/crypto@0.0.0-ci.2cc4cdc", "", { "dependencies": { "@zk-kit/baby-jubjub": "^1.0.3", "@zk-kit/eddsa-poseidon": "^1.1.0", "@zk-kit/poseidon-cipher": "^0.3.2", "ethers": "^6.14.0" } }, "sha512-tzmIxwoEH+LNNgBRlnK/3IfCGC+umZxsz92P57SRA6L65XXYTMURrHnxaTcHVZlumnJPYHn1cPIWI3HoI8ERIQ=="],
320320

321-
"@maci-protocol/domainobjs": ["@maci-protocol/domainobjs@0.0.0-ci.2b67e0e", "", { "dependencies": { "@maci-protocol/crypto": "0.0.0-ci.2b67e0e" } }, "sha512-X3nJSFr87RaCfwpM7iZJphMJDjIAc5KAagCsDjaAvbZrIgZxNn5V3++ris1sJd0SdjYzpFU/Ochn9TGnrpZOmg=="],
321+
"@maci-protocol/domainobjs": ["@maci-protocol/domainobjs@0.0.0-ci.2cc4cdc", "", { "dependencies": { "@maci-protocol/crypto": "0.0.0-ci.2cc4cdc" } }, "sha512-vuD+2WoCw+dGCBwVqaeaKPEAeG+mWhQ29UMXNMUFBZwREgXgLX875zjYGLo4fNhvmECB7vaJtqzzzN9ZOb4p2w=="],
322322

323-
"@maci-protocol/sdk": ["@maci-protocol/sdk@0.0.0-ci.2b67e0e", "", { "dependencies": { "@maci-protocol/contracts": "0.0.0-ci.2b67e0e", "@maci-protocol/core": "0.0.0-ci.2b67e0e", "@maci-protocol/crypto": "0.0.0-ci.2b67e0e", "@maci-protocol/domainobjs": "0.0.0-ci.2b67e0e", "@zk-kit/lean-imt": "^2.2.3", "ethers": "^6.14.0", "multiformats": "9.9.0", "snarkjs": "^0.7.5" }, "bin": { "maci-sdk": "./build/ts/index.js" } }, "sha512-KE957AHfcdE54r/tSu9058Jmf8AxhgMmUG7mupPryAakd2BaRgdQNfmKbM9Vwg/oIXcDSXZQgCWUQ02mjI0BDw=="],
323+
"@maci-protocol/sdk": ["@maci-protocol/sdk@0.0.0-ci.2cc4cdc", "", { "dependencies": { "@maci-protocol/contracts": "0.0.0-ci.2cc4cdc", "@maci-protocol/core": "0.0.0-ci.2cc4cdc", "@maci-protocol/crypto": "0.0.0-ci.2cc4cdc", "@maci-protocol/domainobjs": "0.0.0-ci.2cc4cdc", "@zk-kit/lean-imt": "^2.2.3", "ethers": "^6.14.0", "multiformats": "9.9.0", "snarkjs": "^0.7.5" }, "bin": { "maci-sdk": "./build/ts/index.js" } }, "sha512-YUAq6c1Ngh3H1sCViRKw2k2gqz6ekitZI1Ut9okvnv1OnxRwx7zGW1lqnxSe0AVKBOn0WHrmJ5RsmU6CKizvdw=="],
324324

325325
"@metamask/abi-utils": ["@metamask/abi-utils@2.0.4", "", { "dependencies": { "@metamask/superstruct": "^3.1.0", "@metamask/utils": "^9.0.0" } }, "sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ=="],
326326

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"@layerzerolabs/lz-definitions": "^2.3.27",
2626
"@layerzerolabs/lz-v2-utilities": "^2.3.27",
2727
"@layerzerolabs/scan-client": "^0.0.8",
28-
"@maci-protocol/domainobjs": "0.0.0-ci.2b67e0e",
29-
"@maci-protocol/sdk": "0.0.0-ci.2b67e0e",
28+
"@maci-protocol/domainobjs": "0.0.0-ci.2cc4cdc",
29+
"@maci-protocol/sdk": "0.0.0-ci.2cc4cdc",
3030
"@react-native-async-storage/async-storage": "^1.23.1",
3131
"@shazow/whatsabi": "0.11.0",
3232
"@tanstack/query-async-storage-persister": "^5.49.1",

plugins/maciVoting/components/MaciCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
33
import { useMaci } from "../hooks/useMaci";
44

55
const MaciCard = () => {
6-
const { onSignup, maciKeypair, isRegistered, createKeypair, error: maciError } = useMaci();
6+
const { onSignup, maciKeypair, isRegistered, isLoading, createKeypair, error: maciError } = useMaci();
77
const [error, setError] = useState<string | undefined>(undefined);
88

99
useEffect(() => {
@@ -37,7 +37,7 @@ const MaciCard = () => {
3737
<p>You need to sign up your locally generated public key to the main Maci contract.</p>
3838
<p className="text-sm text-critical-500">{error}</p>
3939
</div>
40-
<Button onClick={onClick} disabled={isRegistered}>
40+
<Button onClick={onClick} disabled={isRegistered ?? isLoading}>
4141
{buttonMessage}
4242
</Button>
4343
</Card>

plugins/maciVoting/components/PollCard.tsx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { Button, Card, Heading } from "@aragon/ods";
2-
import { useCallback, useEffect, useState } from "react";
2+
import { useCallback, useEffect, useMemo, useState } from "react";
33
import { useMaci } from "../hooks/useMaci";
44
import { VoteOption } from "../utils/types";
55

66
const PollCard = ({ pollId }: { pollId: bigint }) => {
77
// check if the user joined the poll
8-
const { setPollId, onJoinPoll, onVote, isRegistered, hasJoinedPoll, error: maciError } = useMaci();
9-
const [error, setError] = useState<string | undefined>(maciError);
8+
const { setPollId, onJoinPoll, onVote, isRegistered, hasJoinedPoll, isLoading, error: maciError } = useMaci();
9+
const [error, setError] = useState<string | undefined>(undefined);
10+
11+
useEffect(() => {
12+
setError(maciError);
13+
}, [maciError]);
1014

1115
useEffect(() => {
1216
setPollId(pollId);
@@ -34,6 +38,16 @@ const PollCard = ({ pollId }: { pollId: bigint }) => {
3438
[onVote]
3539
);
3640

41+
const buttonMessage = useMemo(() => {
42+
if (hasJoinedPoll) {
43+
return "Already joined poll";
44+
}
45+
if (isLoading) {
46+
return "Joining poll...";
47+
}
48+
return "Join poll";
49+
}, [hasJoinedPoll, isLoading]);
50+
3751
return (
3852
<Card className="flex flex-col gap-y-4 p-6 shadow-neutral">
3953
<Heading size="h3">MACI Poll</Heading>
@@ -46,9 +60,20 @@ const PollCard = ({ pollId }: { pollId: bigint }) => {
4660
<div className="flex flex-col justify-between gap-y-2">
4761
<p>Submit your vote anonymously to the poll. Results will be tallied after the voting period ends.</p>
4862
<div className="flex flex-row gap-x-1">
49-
<Button onClick={() => onClickVote(VoteOption.Yes)}>Yes</Button>
50-
<Button onClick={() => onClickVote(VoteOption.No)}>No</Button>
51-
<Button onClick={() => onClickVote(VoteOption.Abstain)}>Abstain</Button>
63+
<Button onClick={() => onClickVote(VoteOption.Yes)} disabled={isLoading} size="sm" variant="success">
64+
Yes
65+
</Button>
66+
<Button onClick={() => onClickVote(VoteOption.No)} disabled={isLoading} size="sm" variant="critical">
67+
No
68+
</Button>
69+
<Button
70+
onClick={() => onClickVote(VoteOption.Abstain)}
71+
disabled={isLoading}
72+
size="sm"
73+
variant="warning"
74+
>
75+
Abstain
76+
</Button>
5277
</div>
5378
</div>
5479
) : (
@@ -57,7 +82,9 @@ const PollCard = ({ pollId }: { pollId: bigint }) => {
5782
In order to submit your vote you need to join the poll using your locally generated MACI public key and
5883
any wallet you want.
5984
</p>
60-
<Button onClick={onClickJoinPoll}>Join poll</Button>
85+
<Button onClick={onClickJoinPoll} disabled={hasJoinedPoll || isLoading}>
86+
{buttonMessage}
87+
</Button>
6188
</div>
6289
)}
6390
</>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { useEffect, useMemo } from "react";
2+
import { useCoordinator } from "../../hooks/useCoordinator";
3+
import { Button } from "@aragon/ods";
4+
import { useAlerts } from "@/context/Alerts";
5+
6+
interface IFinalizeActionProps {
7+
pollId: number;
8+
}
9+
10+
export const FinalizeAction: React.FC<IFinalizeActionProps> = ({ pollId }) => {
11+
const { finalizeStatus, finalizeProposal } = useCoordinator();
12+
const { addAlert } = useAlerts();
13+
14+
const finalizationMessage = useMemo(() => {
15+
switch (finalizeStatus) {
16+
case "notStarted":
17+
return "";
18+
case "merging":
19+
return "Merging poll...";
20+
case "merged":
21+
return "The poll has been merged.";
22+
case "proving":
23+
return "Generating proofs...";
24+
case "proved":
25+
return "The proofs have been generated.";
26+
case "submitting":
27+
return "Submitting proofs...";
28+
case "submitted":
29+
return "The proofs have been submitted. You can now execute the proposal.";
30+
default:
31+
return "";
32+
}
33+
}, [finalizeStatus]);
34+
35+
useEffect(() => {
36+
if (finalizeStatus === "notStarted") return;
37+
if (finalizeStatus === "merging") {
38+
addAlert("Votes merging", {
39+
description: "The votes are being merged.",
40+
type: "info",
41+
});
42+
}
43+
if (finalizeStatus === "merged") {
44+
addAlert("Votes merged", {
45+
description: "The votes have been merged.",
46+
type: "success",
47+
});
48+
}
49+
if (finalizeStatus === "proving") {
50+
addAlert("Votes proving", {
51+
description: "The votes are being proved.",
52+
type: "info",
53+
});
54+
}
55+
if (finalizeStatus === "proved") {
56+
addAlert("Votes proved", {
57+
description: "The votes have been proved.",
58+
type: "success",
59+
});
60+
}
61+
if (finalizeStatus === "submitting") {
62+
addAlert("Submitting votes.", {
63+
description: "The votes are being submitted.",
64+
type: "info",
65+
});
66+
}
67+
if (finalizeStatus === "submitted") {
68+
addAlert("Votes submitted", {
69+
description: "The votes have been submitted.",
70+
type: "success",
71+
});
72+
}
73+
}, [finalizeStatus]);
74+
75+
return (
76+
<div className="overflow-hidden rounded-xl bg-neutral-0 pb-2 shadow-neutral">
77+
<div className="flex flex-col gap-y-2 px-4 py-4 md:gap-y-3 md:px-6 md:py-6">
78+
<div className="flex justify-between gap-x-2 gap-y-2">
79+
<p className="text-xl leading-tight text-neutral-800 md:text-2xl">Finalize Poll</p>
80+
<Button size="md" disabled={finalizeStatus !== "notStarted"} onClick={() => finalizeProposal(pollId)}>
81+
Finalize
82+
</Button>
83+
</div>
84+
<p className="text-base leading-normal text-neutral-500 md:text-lg">
85+
The poll must have ended in order for it to be finalized.
86+
</p>
87+
<p className="text-sm text-info-500">{finalizationMessage}</p>
88+
</div>
89+
</div>
90+
);
91+
};

0 commit comments

Comments
 (0)