Skip to content

Commit a0781bd

Browse files
committed
feat: frontend solution pupup logic draft
1 parent f8e3e5d commit a0781bd

File tree

4 files changed

+444
-12
lines changed

4 files changed

+444
-12
lines changed

frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@libp2p/interfaces": "^3.3.2",
1919
"@tanstack/react-query": "^5.85.5",
2020
"@types/circomlibjs": "^0.1.6",
21+
"@types/snarkjs": "^0.7.9",
2122
"buffer": "^6.0.3",
2223
"circomlibjs": "^0.1.2",
2324
"ethers": "^6.15.0",
@@ -26,6 +27,7 @@
2627
"process": "^0.11.10",
2728
"react": "^19.1.0",
2829
"react-dom": "^19.1.0",
30+
"snarkjs": "^0.7.5",
2931
"util": "^0.12.5"
3032
},
3133
"devDependencies": {

frontend/src/components/SolutionPopUp.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import Popup from "./PopUp";
33
import "../styles/SolutionPopUp.css"
44

55
type SolutionPopUpProps = {
6-
onSubmit: (data: string) => void;
6+
onSubmit: (data: number) => void;
77
isOpen: boolean;
88
onClose: () => void;
99
}
1010

1111
function SolutionPopUp({ onSubmit, isOpen, onClose }: SolutionPopUpProps) {
12-
const [solution, setSolution] = useState<string>("")
12+
const [solution, setSolution] = useState<number>(0)
1313

1414
const handleSubmit = (e: React.FormEvent) => {
1515
e.preventDefault();
@@ -21,7 +21,7 @@ function SolutionPopUp({ onSubmit, isOpen, onClose }: SolutionPopUpProps) {
2121
<form className="solution-form" onSubmit={handleSubmit}>
2222
<label>
2323
Secreat
24-
<input type="text" value={solution} onChange={(e) => setSolution(e.target.value)} required />
24+
<input type="number" value={solution} onChange={(e) => setSolution(Number(e.target.value))} required />
2525
</label>
2626
<button type="submit">
2727
Submit solution

frontend/src/containers/SolutionPopUpContainer.tsx

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,85 @@
1-
import { useState } from "react";
1+
import { useState, useEffect } from "react";
22
import SolutionPopUp from "../components/SolutionPopUp";
33
import { FilledButton } from "../components/Buttons";
44
import { useAlert } from "../context/AlertContext";
5+
import { useWallet } from "../context/WalletContext";
6+
import computeCommit from "../utils/computeCommit";
7+
import TaskManagerAbi from "../../../abi/TaskManagerAbi.json";
8+
import * as snarkjs from "snarkjs";
59

610

711
function SolutionPopUpContainer() {
812
const [isOpen, setIsOpen] = useState(false);
13+
const [contractAddress, setContractAddress] = useState<string>("");
14+
//const { signer, account } = useWallet();
915
const { showAlert } = useAlert();
1016

17+
// Fetch contract address once when popup opens
18+
useEffect(() => {
19+
if (isOpen) {
20+
(async () => {
21+
try {
22+
const res = await fetch("/api/contract-address");
23+
const json = await res.json();
24+
setContractAddress(json.address);
25+
} catch (e) {
26+
showAlert("error", "Failed to fetch contract address", 4000);
27+
}
28+
})();
29+
}
30+
}, [isOpen]);
1131

12-
const handleSolutionSubmit = (solution: string) => {
32+
const handleSolutionSubmit = async (solution: number) => {
33+
/*
34+
// Call TaskManager smart contract
35+
try {
36+
if (!signer) throw new Error("Wallet not connected");
37+
const contract = new (window as any).ethers.Contract(
38+
contractAddress,
39+
TaskManagerAbi,
40+
signer
41+
);
1342
43+
// TODO: Missing taskId and salt. Need to fetch them from backend with other task data!
44+
// TODO: Fix input
45+
// Prepare input for the circuit
46+
const commit = await computeCommit(BigInt(solution), salt);
47+
const input = {
48+
solution: BigInt(solution),
49+
taskId: BigInt(taskId),
50+
taskSalt: salt,
51+
commit: commit,
52+
recipient: account
53+
};
54+
55+
const { proof, publicSignals } = await snarkjs.groth16.fullProve(input, "/TaskProof.wasm", "/TaskProof_final.zkey");
56+
// build calldata
57+
const calldata = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals);
58+
const argv = calldata.replace(/["[\]\s]/g, "").split(",").map(x => BigInt(x).toString());
59+
60+
const a = [argv[0], argv[1]];
61+
const b = [[argv[2], argv[3]], [argv[4], argv[5]]];
62+
const c = [argv[6], argv[7]];
63+
const publicInputs = argv.slice(8); // should be [commit, taskId, taskSalt, recipient]
64+
65+
const tx = await contract.solveTask(
66+
taskId,
67+
account, // My wallet address
68+
a,
69+
b,
70+
c,
71+
publicInputs
72+
);
73+
await tx.wait();
74+
showAlert("success", `Task solved`, 4000);
75+
} catch (e) {
76+
console.log(e);
77+
showAlert("error", "Failed to call smart contract", 4000);
78+
return;
79+
}
80+
setIsOpen(false);
1481
showAlert("info", `Task solution: "${solution}" subbmited!`, 4000);
82+
*/
1583
}
1684

1785

0 commit comments

Comments
 (0)