Circom desktop solution

circom-desktop
ioedeveloper 3 months ago
parent faee0085b1
commit 431059fdf8
  1. 26
      apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts
  2. 97
      apps/remixdesktop/src/tools/circom.ts

@ -1,6 +1,7 @@
import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron" import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron"
import { Profile } from "@remixproject/plugin-utils" import { Profile } from "@remixproject/plugin-utils"
import { circomCli } from "../tools/circom" import { circomCli } from "../tools/circom"
import path from "path"
const profile: Profile = { const profile: Profile = {
displayName: 'circom', displayName: 'circom',
@ -15,12 +16,6 @@ export class CircomElectronPlugin extends ElectronBasePlugin {
super(profile, clientProfile, CircomElectronPluginClient) super(profile, clientProfile, CircomElectronPluginClient)
this.methods = [...super.methods] this.methods = [...super.methods]
} }
async onActivation(): Promise<void> {
console.log('activating to exec')
if (!(await circomCli.isCargoInstalled())) await circomCli.installRustup()
if (!(await circomCli.isCircomInstalled())) await circomCli.installCircom()
}
} }
const clientProfile: Profile = { const clientProfile: Profile = {
@ -31,15 +26,28 @@ const clientProfile: Profile = {
} }
class CircomElectronPluginClient extends ElectronBasePluginClient { class CircomElectronPluginClient extends ElectronBasePluginClient {
circomIsInstalled: boolean = false isCircomInstalled: boolean = false
constructor(webContentsId: number, profile: Profile) { constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile) super(webContentsId, profile)
this.onload() this.onload()
} }
async compile() { async install() {
console.log('compiling circom circuit...') this.isCircomInstalled = await circomCli.isCircomInstalled()
if (!this.isCircomInstalled) {
await circomCli.installCircom()
this.isCircomInstalled = true
}
}
async compile(filePath: string) {
if (!this.isCircomInstalled) await this.install()
// @ts-ignore
const wd = await this.call('fs', 'getWorkingDir')
filePath = path.join(wd, filePath)
console.log('Running circom compilation for ', filePath)
await circomCli.run(filePath)
} }
parse(): void { parse(): void {

@ -1,37 +1,74 @@
import { app } from 'electron' import { app } from 'electron'
import { promisify } from 'util' import { promisify } from 'util'
import { exec } from 'child_process' import { exec } from 'child_process'
import { gitProxy } from './git'
import path from 'path' import path from 'path'
import { existsSync } from 'fs' import fs, { existsSync } from 'fs'
import axios from 'axios'
const execAsync = promisify(exec) const execAsync = promisify(exec)
const CIRCOM_INSTALLATION_PATH = getInstallationPath()
const CIRCOM_INSTALLATION_URL = getInstallationUrl()
export const circomCli = { async function downloadFile(url: string, dest: string) {
async installRustup () { const writer = fs.createWriteStream(dest)
try { const response = await axios({
if (process.platform !== 'win32') { url,
console.log('installing rustup for unix') method: 'GET',
const { stdout } = await execAsync(`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y`) responseType: 'stream'
})
console.log('stdout: ', stdout) response.data.pipe(writer)
} else {
console.log('installing rustup for windows') return new Promise((resolve, reject) => {
writer.on('finish', () => {
if (process.platform !== 'win32') {
// Make the file executable
fs.chmod(dest, 0o755, (err) => {
if (err) {
reject(`Error making file executable: ${err}`)
} else {
resolve(dest)
}
})
} }
} catch (e) { resolve(true)
console.error(e) })
} writer.on('error', reject)
}, })
}
function getInstallationPath() {
switch (process.platform) {
case 'win32':
return path.join(app.getPath('temp'), 'circom-windows-amd64.exe')
case 'darwin':
return path.join(app.getAppPath(), 'circom-macos-amd64')
case 'linux':
return path.join(app.getAppPath(), 'circom-linux-amd64')
}
}
function getInstallationUrl() {
switch (process.platform) {
case 'win32':
return "https://github.com/iden3/circom/releases/latest/download/circom-windows-amd64.exe"
case 'darwin':
return "https://github.com/iden3/circom/releases/latest/download/circom-macos-amd64"
case 'linux':
return "https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64"
}
}
export const circomCli = {
async installCircom () { async installCircom () {
try { try {
const appPath = app.getAppPath() console.log('downloading circom to ', CIRCOM_INSTALLATION_PATH)
const targetPath = path.join(appPath, 'bin') await downloadFile(CIRCOM_INSTALLATION_URL, CIRCOM_INSTALLATION_PATH)
console.log('downloading done')
console.log('cloning circom repo to ' + targetPath)
if (!existsSync(`${targetPath}/circom`)) await gitProxy.clone('https://github.com/iden3/circom.git', targetPath)
console.log('builing circom with cargo')
await execAsync(`cd ${targetPath}/circom && cargo build --release && cargo install --path circom`)
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
@ -39,21 +76,17 @@ export const circomCli = {
async isCircomInstalled () { async isCircomInstalled () {
try { try {
await execAsync(`circom --version`) return existsSync(CIRCOM_INSTALLATION_PATH)
return true
} catch (e) { } catch (e) {
return false return false
} }
}, },
async isCargoInstalled () { async run (filePath: string, options?: Record<string, string>) {
try { const cmd = `${CIRCOM_INSTALLATION_PATH} ${filePath} ${Object.keys(options || {}).map((key) => `--${key} ${options[key]}`).join(' ')}`
await execAsync(`cargo version`) const { stdout, stderr } = await execAsync(cmd)
return true if (stderr) return console.error(stderr)
} catch (e) { console.log(stdout)
return false
}
} }
} }
Loading…
Cancel
Save