Created
October 19, 2023 10:41
-
-
Save yann300/02f57fed8677d4f4fe26d5bf5a66eac5 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.18+commit.87f61d96.js&optimize=false&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NOTE: Install dependencies with `npm i axios form-data`. | |
const axios = require('axios'); | |
const FormData = require("form-data"); | |
const tar = require('tar'); | |
// NOTE: Provide your API key here. | |
const API_KEY = "qmZtKNT5swfCkkHVoZZ8N2HKv656jFXx"; | |
const API_VERSION = "v1"; | |
const API_URL = `https://forge.sindri.app/api/${API_VERSION}`; | |
const apiKeyQueryString = `?api_key=${API_KEY}`; | |
const headersUrlEncode = { | |
Accept: "application/json", | |
"Content-Type": "application/x-www-form-urlencoded", | |
}; | |
// Utility to poll a detail API endpoint until the status is `Ready` or `Failed`. | |
// Returns the response object of the final request or throws an error if the timeout is reached. | |
async function pollForStatus(endpoint, timeout = 20 * 60) { | |
for (let i = 0; i < timeout; i++) { | |
const response = await axios.get(API_URL + endpoint + apiKeyQueryString, { | |
headers: headersUrlEncode, | |
validateStatus: (status) => status === 200, | |
}); | |
const status = response.data.status; | |
console.log(response.data) | |
if (["Ready", "Failed"].includes(status)) { | |
console.log(`Poll exited after ${i} seconds with status: ${status}`); | |
return response; | |
} | |
await new Promise((r) => setTimeout(r, 1000)); | |
} | |
throw new Error(`Polling timed out after ${timeout} seconds.`); | |
} | |
async function main() { | |
try { | |
// Create a new circuit. | |
console.log("1. Creating circuit..."); | |
const createResponse = await axios.post( | |
API_URL + "/circuit/create" + apiKeyQueryString, | |
{ | |
circuit_name: "multiplier_example", | |
circuit_type: "Circom C Groth16 bn254", | |
}, | |
{ headers: headersUrlEncode, validateStatus: (status) => status === 201 }, | |
); | |
const circuitId = createResponse.data.circuit_id; | |
// Load the circuit's `tar.gz` file. | |
const circuit = await remix.call('fileManager', 'readFile', './scripts/multiplier2.circom') | |
const tape = new tar.TarWriter() | |
tape.addTextFile('multiplier2.circom', circuit) | |
// Upload the circuit file. | |
const uploadFormData = new FormData(); | |
uploadFormData.append("files", await tape.writeBlob(), "multiplier2.tar.gz"); | |
await axios.post( | |
API_URL + `/circuit/${circuitId}/uploadfiles` + apiKeyQueryString, | |
uploadFormData, | |
{ validateStatus: (status) => status === 201 }, | |
); | |
// Initiate circuit compilation. | |
await axios.post( | |
API_URL + `/circuit/${circuitId}/compile` + apiKeyQueryString, | |
{ validateStatus: (status) => status === 201 }, | |
); | |
// Poll the circuit detail endpoint until the compilation status is `Ready` or `Failed`. | |
const { | |
data: { status: compileStatus }, | |
} = await pollForStatus(`/circuit/${circuitId}/detail`); | |
// Check for compilation issues. | |
if (compileStatus === "Failed") { | |
throw new Error("Circuit compilation failed."); | |
} | |
console.log("Circuit compilation succeeded!"); | |
// Initiate proof generation. | |
console.log("2. Proving circuit..."); | |
const proofInput = JSON.stringify({ a: "7", b: "42" }); | |
const proveResponse = await axios.post( | |
API_URL + `/circuit/${circuitId}/prove` + apiKeyQueryString, | |
{ proof_input: proofInput }, | |
{ headers: headersUrlEncode, validateStatus: (status) => status === 201 }, | |
); | |
const proofId = proveResponse.data.proof_id; | |
// Poll the proof detail endpoint until the compilation status is `Ready` or `Failed`. | |
const proofDetailResponse = await pollForStatus(`/proof/${proofId}/detail`); | |
// Check for proving issues. | |
const proofDetailStatus = proveResponse.data.status; | |
if (proofDetailStatus === "Failed") { | |
throw new Error("Proving failed"); | |
} | |
// Retrieve output from the proof. | |
const publicOutput = proofDetailResponse.data.public[0]; | |
console.log(`Circuit proof output signal: ${publicOutput}`); | |
} catch (error) { | |
console.error(error.message); | |
} | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment