|
|
|
@ -1,28 +1,57 @@ |
|
|
|
|
import client from 'sindri' |
|
|
|
|
|
|
|
|
|
const getSindriManifest = async () => { |
|
|
|
|
const sindriJson = await remix.call('fileManager', 'readFile', `sindri.json`) |
|
|
|
|
return JSON.parse(sindriJson) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const normalizePath = (path: string): string => { |
|
|
|
|
while (path.startsWith('/') || path.startsWith('./')) { |
|
|
|
|
path = path.replace(/^(\.\/|\/)/, '') |
|
|
|
|
} |
|
|
|
|
return path |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Compile the given circuit |
|
|
|
|
* @param {string} entryPoint - path to the circuit to compile |
|
|
|
|
* @param {string} apiKey - sindri API key |
|
|
|
|
* @returns {Circuit} compiled circuit |
|
|
|
|
*/ |
|
|
|
|
export const createCircuit = async (entryPoint: string, apiKey: string) => { |
|
|
|
|
export const createCircuit = async (apiKey: string) => { |
|
|
|
|
const sindriManifest = await getSindriManifest() |
|
|
|
|
client.authorize({apiKey}) |
|
|
|
|
|
|
|
|
|
const sindriConf = await remix.call('fileManager', 'readFile', `sindri.json`) |
|
|
|
|
const circuit = await remix.call('fileManager', 'readFile', entryPoint) |
|
|
|
|
const deps = await remix.call('circuit-compiler' as any, 'resolveDependencies', entryPoint, circuit) |
|
|
|
|
|
|
|
|
|
const files = [] |
|
|
|
|
files.push(new File([circuit], 'circuit.circom')) |
|
|
|
|
files.push(new File([sindriConf], 'sindri.json'))
|
|
|
|
|
// Create a map from file paths to `File` objects for all files in the workspace.
|
|
|
|
|
const filesByPath: {[path: string]: File} = {} |
|
|
|
|
interface Workspace { |
|
|
|
|
children?: Workspace |
|
|
|
|
content?: string |
|
|
|
|
} |
|
|
|
|
const workspace: Workspace = await remix.call('fileManager', 'copyFolderToJson', '/') |
|
|
|
|
const childQueue: Array<[string, Workspace]> = Object.entries(workspace) |
|
|
|
|
while (childQueue.length > 0) { |
|
|
|
|
const [path, child] = childQueue.pop() |
|
|
|
|
if ('content' in child) { |
|
|
|
|
filesByPath[path] = new File([child.content], path) |
|
|
|
|
} |
|
|
|
|
if ('children' in child) { |
|
|
|
|
childQueue.push(...Object.entries(child.children)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (const file in deps) { |
|
|
|
|
if (file === entryPoint) continue |
|
|
|
|
files.push(new File([deps[file]], file)) |
|
|
|
|
// Merge any of the circuit's resolved dependencies into the files at their expected import paths.
|
|
|
|
|
if (sindriManifest.circuitType === 'circom') { |
|
|
|
|
const circuitPath = normalizePath(sindriManifest.circuitPath || 'circuit.circom') |
|
|
|
|
const circuitContent = await remix.call('fileManager', 'readFile', circuitPath) |
|
|
|
|
const dependencies: {[path: string]: string} = await remix.call('circuit-compiler' as any, 'resolveDependencies', circuitPath, circuitContent) |
|
|
|
|
Object.entries(dependencies).forEach(([rawPath, content]) => { |
|
|
|
|
const path = normalizePath(rawPath) |
|
|
|
|
filesByPath[path] = new File([content], path) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log(`creating circuit "${entryPoint}"...`) |
|
|
|
|
const files = Object.values(filesByPath) |
|
|
|
|
const circuitProject = await client.createCircuit(files) |
|
|
|
|
console.log(`circuit created ${circuitProject.circuit_id}`) |
|
|
|
|
return circuitProject |
|
|
|
@ -30,33 +59,17 @@ export const createCircuit = async (entryPoint: string, apiKey: string) => { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Generate a proof against the given circuit |
|
|
|
|
* @param {string} circuitId - id of the circuit |
|
|
|
|
* @param {Object} signals - input signals |
|
|
|
|
* @param {string} apiKey - sindri API key |
|
|
|
|
* @returns {Proof} generated proof |
|
|
|
|
*/ |
|
|
|
|
export const proveCircuit = async (circuitId: string, signals: { [id: string]: string }, apiKey: string) => { |
|
|
|
|
export const proveCircuit = async (signals: {[id: string]: string}, apiKey: string) => { |
|
|
|
|
const sindriManifest = await getSindriManifest() |
|
|
|
|
client.authorize({apiKey}) |
|
|
|
|
console.log(`proving circuit ${circuitId}...`) |
|
|
|
|
const proof = await client.proveCircuit(circuitId, JSON.stringify(signals)) |
|
|
|
|
|
|
|
|
|
const circuitName = sindriManifest.name |
|
|
|
|
console.log(`proving circuit "${circuitName}"...`) |
|
|
|
|
const proof = await client.proveCircuit(circuitName, JSON.stringify(signals)) |
|
|
|
|
console.log(`proof id: ${proof.proof_id}`) |
|
|
|
|
return proof |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Save the circuit
|
|
|
|
|
* @param {Circuit} circuitProject - compiled circuit |
|
|
|
|
*/ |
|
|
|
|
export const saveCircuit = async (circuitProject) => { |
|
|
|
|
await remix.call('fileManager', 'writeFile', `.sindri/${circuitProject.circuit_id}.json`, JSON.stringify(circuitProject, null, '\t'))
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Load the circuit
|
|
|
|
|
* @param {string} circuitId - id of the circuit |
|
|
|
|
* @param {Object} signals - input signals |
|
|
|
|
* @returns {Proof} generated proof |
|
|
|
|
*/ |
|
|
|
|
export const loadCircuit = async (circuitId: string) => { |
|
|
|
|
return JSON.parse(await remix.call('fileManager', 'readFile', `.sindri/${circuitId}.json`)) |
|
|
|
|
} |
|
|
|
|