Skip to content

Commit

Permalink
Merge pull request #23 from hollow-leaf/feat/addGenZkproof
Browse files Browse the repository at this point in the history
Feat: add gen zkproof
  • Loading branch information
yeeetai authored Aug 23, 2023
2 parents 4e950e2 + 9f309fe commit d1b2768
Show file tree
Hide file tree
Showing 19 changed files with 2,873 additions and 261 deletions.
Binary file added apps/web/public/circuits.wasm
Binary file not shown.
Binary file added apps/web/public/circuits.zkey
Binary file not shown.
37 changes: 12 additions & 25 deletions apps/web/src/app/vote/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import WebcamCapture from '../../components/Webcam/WebcamCapture'
import ProcessDialog from '../../components/Dialog/ProcessDialog'
import GenerateProof from '../../components/ZK/GenerateProof'
import VerifyProof from '../../components/ZK/VerifyProof'
import CreateProposal from '../../components/Contract/CreateProposal'
import ProcessLoading from '../../components/Loading/ProcessLoading'
import KamuiLoading from '../../components/Loading/KamuiLoading'
Expand All @@ -24,12 +23,11 @@ export default function Vote() {
const [isVerifyDialogOpen, setIsVerifyDialogOpen] = useState(false)
const [isGenProofDialogOpen, setIsGenProofDialogOpen] = useState(false)
const [isCreateProposalDialogOpen, setIsCreateProposalDialogOpen] = useState(false)
const [isVerified, setVerified] = useState(false)
const [imgSrc, setImgSrc] = useState(null)
const [copied, setCopied] = useState(false)
const [proposals, setProposals] = useState<any>([]);
const [proposalStatus, setProposalStatus] = useState("init")
const [credentialHash, setCredentialHash] = useState("");
const [proof, setProof] = useState(null)

const openCaptureDialog = async () => {
setIsCaptureDialogOpen(!isCaptureDialogOpen);
Expand Down Expand Up @@ -60,8 +58,9 @@ export default function Vote() {
} else {
setMounted(false)
}
setProof(false)
}, [address, isConnected])

useEffect(() => {
getProposals().then((res) => {
setProposals(res);
Expand All @@ -78,9 +77,9 @@ export default function Vote() {
<p className='font-mono text-black font-bold text-3xl dark:text-white my-4'>
Account Status
</p>
{isVerified
? <div className='badge badge-accent'>Verified</div>
: <div className='badge badge-secondary'>Unverified</div>
{proof
? <div className='badge badge-accent'>Generated</div>
: <div className='badge badge-secondary'>UnGenerated</div>
}
</div>
<div className='flex flex-row py-2 space-x-11 justify-center'>
Expand All @@ -100,15 +99,9 @@ export default function Vote() {
}
</div>
</div>
<div className='flex flex-col items-center space-y-5'>
<span className='font-mono'>3. Input Proof to KYC</span>
<div className='bg-gradient-to-r from-[#42275a] to-[#734b6d] card w-[350px] p-4 text-white shadow-[0_3px_10px_rgb(0,0,0,0.2)]'>
<div className='btn btn-ghost' onClick={openVerifyDialog}>Verify Proof</div>
</div>
</div>
</div>
<div className='divider'></div>
<div className='container w-full flex flex-row space-x-3 items-center'>
<div className='container w-full flex flex-row space-x-3 items-center mb-8'>
<div className="flex w-full justify-start">
<p className='font-mono text-black font-bold text-3xl dark:text-white my-4'>
KAMUI FIELD
Expand Down Expand Up @@ -140,15 +133,18 @@ export default function Vote() {
acceptCount={Number(acceptCount)}
denyCount={Number(denyCount)}
endTime={Number(endTime)}
credentialHash={credentialHash}
proof={proof}
status={status}
key={index}
setIsLoading={setIsLoading}
/>
);
}
})}
</div>
</div>
{isLoading && <ProcessLoading />}
{isKamuiLoading && <KamuiLoading />}
<ProcessDialog
isOpen={isCaptureDialogOpen}
onClose={() => setIsCaptureDialogOpen(false)}
Expand All @@ -161,14 +157,7 @@ export default function Vote() {
onClose={() => setIsGenProofDialogOpen(false)}
title={'Generate proof'}
>
<GenerateProof imgSrc={imgSrc} handleCopyClick={handleCopyClick} setIsLoading={setIsLoading} onClose={() => setIsGenProofDialogOpen(false)} />
</ProcessDialog>
<ProcessDialog
isOpen={isVerifyDialogOpen}
onClose={() => setIsVerifyDialogOpen(false)}
title={'Verify proof'}
>
<VerifyProof setVerified={setVerified} setIsLoading={setIsLoading} onClose={() => setIsVerifyDialogOpen(false)} />
<GenerateProof imgSrc={imgSrc} handleCopyClick={handleCopyClick} setProof={setProof} setIsLoading={setIsLoading} onClose={() => setIsGenProofDialogOpen(false)} />
</ProcessDialog>
<ProcessDialog
isOpen={isCreateProposalDialogOpen}
Expand All @@ -177,8 +166,6 @@ export default function Vote() {
>
<CreateProposal setIsLoading={setIsLoading} onClose={() => setIsCreateProposalDialogOpen(false)} />
</ProcessDialog>
{isLoading && <ProcessLoading />}
{isKamuiLoading && <KamuiLoading />}
{
copied &&
<div className='toast toast-top toast-end'>
Expand Down
62 changes: 31 additions & 31 deletions apps/web/src/components/Card/ProposalCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useRouter } from "next/router";
import VoteConfirm from '../Contract/VoteConfirm'
import ProcessDialog from '../../components/Dialog/ProcessDialog'

import { vote } from "../../service/kamui/contract";
import SmallCountdown from "../Countdown/SmallCountdown";
import { useEffect } from "react";
import { useState, useEffect } from "react";
import dayjs from "dayjs";

export interface ProposalCard {
Expand All @@ -11,27 +13,14 @@ export interface ProposalCard {
denyCount: any,
creator: string,
endTime: any,
credentialHash: string
proof: any
status: string
setIsLoading: any
}

const ProposalCard = (props: ProposalCard) => {
// const router = useRouter();
// function handleClick() {
// router.push({
// pathname: "/card",
// query: {
// proposalId: props.proposalId,
// proposalBody: props.proposalBody,
// acceptCount: props.acceptCount.toString(),
// denyCount: props.denyCount.toString(),
// creator: props.creator,
// endTime: props.endTime.toString(),
// credentialHash: props.credentialHash,
// status: props.status,
// },
// });
// }
const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false)
const [action, setAction] = useState(null)

function calPercentage(): number | string {
if (props.denyCount === 0 && props.acceptCount === 0)
Expand All @@ -51,15 +40,18 @@ const ProposalCard = (props: ProposalCard) => {
return Number(Number(num.toFixed(3)).toFixed(2));
}

function handleAccept(e: any) {
vote(props.credentialHash, props.proposalId, true);
e.stopPropagation();
async function handleAccept() {
setAction(true)
setIsConfirmDialogOpen(true)
}

function handleDeny(e: any) {
vote(props.credentialHash, props.proposalId, false);
e.stopPropagation();
async function handleDeny() {
setAction(false)
setIsConfirmDialogOpen(true)


}

return (
<div
className=" card text-white bg-base-100 border-white border-solid border-2 w-[300px] p-2 shadow-[0_3px_10px_rgb(0,0,0,0.2)] mt-3 cursor-pointer "
Expand Down Expand Up @@ -92,9 +84,10 @@ const ProposalCard = (props: ProposalCard) => {
value={calPercentage() === "no vote" ? 0 : calPercentage()}
max="100"
></progress>
<div className="flex justify-between mt-7">
{props.status === "Closed" ? (
<>
<div className="flex justify-center mt-7">
{props.status === "Closed" || !props.proof ? (
<div className='flex flex-row space-x-12'>

<button
className="btn btn-outline btn-ghost w-20 border-2"
onClick={(e) => { e.stopPropagation() }}
Expand All @@ -107,9 +100,9 @@ const ProposalCard = (props: ProposalCard) => {
>
Deny
</button>
</>
</div>
) : (
<>
<div className='flex flex-row space-x-12'>
<button
className="btn btn-outline btn-success w-20 border-2"
onClick={handleAccept}
Expand All @@ -122,10 +115,17 @@ const ProposalCard = (props: ProposalCard) => {
>
Deny
</button>
</>
</div>
)}
</div>
</div>
<ProcessDialog
isOpen={isConfirmDialogOpen}
onClose={() => setIsConfirmDialogOpen(false)}
title={props.proposalBody}
>
<VoteConfirm setIsLoading={props.setIsLoading} proposalId={props.proposalId} action={action} proof={props.proof} onClose={() => setIsConfirmDialogOpen(false)} />
</ProcessDialog>
</div>
);
}
Expand Down
44 changes: 22 additions & 22 deletions apps/web/src/components/Contract/CreateProposal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createProposal} from '../../service/kamui/contract'
import { createProposal } from '../../service/kamui/contract'
import { useState } from 'react';
import { DateTimePicker } from "@mui/x-date-pickers";
import { sleep } from 'helper'
Expand All @@ -8,7 +8,7 @@ export interface CreateProposalProps {
onClose: any
}

const CreateProposal = ({ setIsLoading, onClose } : CreateProposalProps) => {
const CreateProposal = ({ setIsLoading, onClose }: CreateProposalProps) => {
const [open, setOpen] = useState(false);
const [endTime, setEndTime] = useState<number>(0);
const [content, setContent] = useState<string>('');
Expand All @@ -19,8 +19,8 @@ const CreateProposal = ({ setIsLoading, onClose } : CreateProposalProps) => {
const currentTime = new Date();
const timestamp = Math.floor((datetime.getTime() - currentTime.getTime()) / 1000);
setEndTime(timestamp);
};
};

const handleCreate = async () => {
setIsLoading(true)
await createProposal(content, endTime)
Expand All @@ -29,46 +29,46 @@ const CreateProposal = ({ setIsLoading, onClose } : CreateProposalProps) => {
setFinished(true)
}

return(
return (
<div className='flex flex-col space-y-4 items-center'>
{isFinished
? <>
? <div className='flex flex-col w-[200px] items-center'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="green" className="w-24 h-24 mb-4">
<path fillRule="evenodd" d="M8.603 3.799A4.49 4.49 0 0112 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 013.498 1.307 4.491 4.491 0 011.307 3.497A4.49 4.49 0 0121.75 12a4.49 4.49 0 01-1.549 3.397 4.491 4.491 0 01-1.307 3.497 4.491 4.491 0 01-3.497 1.307A4.49 4.49 0 0112 21.75a4.49 4.49 0 01-3.397-1.549 4.49 4.49 0 01-3.498-1.306 4.491 4.491 0 01-1.307-3.498A4.49 4.49 0 012.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 011.307-3.497 4.49 4.49 0 013.497-1.307zm7.007 6.387a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clipRule="evenodd" />
</svg>
<div className="btn" onClick={onClose} >OK</div>
</>
</div>
: <>
<DateTimePicker
label="End Time"
className="z-50 mt-5 bg-base-100"
onChange={handleEndTimeChange}
sx={{
width: "100%",
"& input": { color: "#A6ADBA" },
/* Change the border color of the outlined input */
".MuiOutlinedInput-root.MuiInputBase-formControl .MuiOutlinedInput-notchedOutline": {
borderColor: "transparent" /* Replace with your desired border color */
},
width: "100%",
"& input": { color: "#A6ADBA" },
/* Change the border color of the outlined input */
".MuiOutlinedInput-root.MuiInputBase-formControl .MuiOutlinedInput-notchedOutline": {
borderColor: "transparent" /* Replace with your desired border color */
},

/* Change the label color */
".MuiInputLabel-root.MuiInputLabel-formControl": {
color: "#A6ADBA"/* Replace with your desired label color */
},
/* Change the label color */
".MuiInputLabel-root.MuiInputLabel-formControl": {
color: "#A6ADBA"/* Replace with your desired label color */
},

".MuiSvgIcon-root": {
fill: "#A6ADBA"
}
".MuiSvgIcon-root": {
fill: "#A6ADBA"
}

}}
/>
<input type="text" placeholder="Content" className="input input-bordered w-[350px] max-w-xs" onChange={(e) => setContent(e.target.value)}/>
<input type="text" placeholder="Content" className="input input-bordered w-[350px] max-w-xs" onChange={(e) => setContent(e.target.value)} />
<div className="btn" onClick={handleCreate}>Create</div>
</>
}
</div>
)

}

export default CreateProposal
54 changes: 54 additions & 0 deletions apps/web/src/components/Contract/VoteConfirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use client'

import React, { useState } from 'react'
import { vote } from "../../service/kamui/contract";


interface VoteContent {
proposalId: number,
action: boolean,
proof: any,
setIsLoading: any,
onClose: any
}

const VoteProposal = ({ proposalId, setIsLoading, action, proof, onClose }: VoteContent) => {
const [isProcess, setProcess] = useState(false)

const handleVote = async () => {
setIsLoading(true)
await vote(proof, proposalId, action);
setIsLoading(false)
setProcess(true)
}

return (
<div className='flex flex-col items-center'>
{
isProcess
? <div className='flex flex-col w-[200px] items-center'>
<div className='mb-4'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="green" className="w-24 h-24">
<path fillRule="evenodd" d="M8.603 3.799A4.49 4.49 0 0112 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 013.498 1.307 4.491 4.491 0 011.307 3.497A4.49 4.49 0 0121.75 12a4.49 4.49 0 01-1.549 3.397 4.491 4.491 0 01-1.307 3.497 4.491 4.491 0 01-3.497 1.307A4.49 4.49 0 0112 21.75a4.49 4.49 0 01-3.397-1.549 4.49 4.49 0 01-3.498-1.306 4.491 4.491 0 01-1.307-3.498A4.49 4.49 0 012.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 011.307-3.497 4.49 4.49 0 013.497-1.307zm7.007 6.387a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clipRule="evenodd" />
</svg>
</div>
<div className="btn" onClick={onClose} >OK</div>
</div>
: <div className='flex flex-col space-y-5 w-[200px] items-center'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" className="w-24 h-24">
<path fillRule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm11.378-3.917c-.89-.777-2.366-.777-3.255 0a.75.75 0 01-.988-1.129c1.454-1.272 3.776-1.272 5.23 0 1.513 1.324 1.513 3.518 0 4.842a3.75 3.75 0 01-.837.552c-.676.328-1.028.774-1.028 1.152v.75a.75.75 0 01-1.5 0v-.75c0-1.279 1.06-2.107 1.875-2.502.182-.088.351-.199.503-.331.83-.727.83-1.857 0-2.584zM12 18a.75.75 0 100-1.5.75.75 0 000 1.5z" clipRule="evenodd" />
</svg>
<div className='font-mono font-bold text-3xl'>{action ? "Accept" : "Deny"}?</div>
<button
className="btn btn-outline btn-warning w-20 border-2"
onClick={handleVote}
>
Confirm
</button>
</div>
}
</div>
)
}

export default VoteProposal
3 changes: 0 additions & 3 deletions apps/web/src/components/Loading/ProcessLoading.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import Image from 'next/image'


const ProcessLoading = (() => {

return (
Expand Down
Loading

0 comments on commit d1b2768

Please sign in to comment.