From 431059fdf80c7c5b8a1d05efe632fca9ba4d6c72 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Fri, 9 Aug 2024 19:46:35 +0100 Subject: [PATCH] Circom desktop solution --- .../src/plugins/circomElectronBasePlugin.ts | 26 +++-- apps/remixdesktop/src/tools/circom.ts | 97 +++++++++++++------ 2 files changed, 82 insertions(+), 41 deletions(-) diff --git a/apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts b/apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts index fd2f58df95..3acc9f7881 100644 --- a/apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts +++ b/apps/remixdesktop/src/plugins/circomElectronBasePlugin.ts @@ -1,6 +1,7 @@ import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron" import { Profile } from "@remixproject/plugin-utils" import { circomCli } from "../tools/circom" +import path from "path" const profile: Profile = { displayName: 'circom', @@ -15,12 +16,6 @@ export class CircomElectronPlugin extends ElectronBasePlugin { super(profile, clientProfile, CircomElectronPluginClient) this.methods = [...super.methods] } - - async onActivation(): Promise { - console.log('activating to exec') - if (!(await circomCli.isCargoInstalled())) await circomCli.installRustup() - if (!(await circomCli.isCircomInstalled())) await circomCli.installCircom() - } } const clientProfile: Profile = { @@ -31,15 +26,28 @@ const clientProfile: Profile = { } class CircomElectronPluginClient extends ElectronBasePluginClient { - circomIsInstalled: boolean = false + isCircomInstalled: boolean = false constructor(webContentsId: number, profile: Profile) { super(webContentsId, profile) this.onload() } - async compile() { - console.log('compiling circom circuit...') + async install() { + 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 { diff --git a/apps/remixdesktop/src/tools/circom.ts b/apps/remixdesktop/src/tools/circom.ts index 975a380588..44eeaa5a45 100644 --- a/apps/remixdesktop/src/tools/circom.ts +++ b/apps/remixdesktop/src/tools/circom.ts @@ -1,37 +1,74 @@ import { app } from 'electron' import { promisify } from 'util' import { exec } from 'child_process' -import { gitProxy } from './git' import path from 'path' -import { existsSync } from 'fs' +import fs, { existsSync } from 'fs' +import axios from 'axios' const execAsync = promisify(exec) +const CIRCOM_INSTALLATION_PATH = getInstallationPath() +const CIRCOM_INSTALLATION_URL = getInstallationUrl() -export const circomCli = { - async installRustup () { - try { - if (process.platform !== 'win32') { - console.log('installing rustup for unix') - const { stdout } = await execAsync(`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y`) +async function downloadFile(url: string, dest: string) { + const writer = fs.createWriteStream(dest) + const response = await axios({ + url, + method: 'GET', + responseType: 'stream' + }) - console.log('stdout: ', stdout) - } else { - console.log('installing rustup for windows') + response.data.pipe(writer) + + 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) { - console.error(e) - } - }, + resolve(true) + }) + 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 () { try { - const appPath = app.getAppPath() - const targetPath = path.join(appPath, 'bin') - - 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`) + console.log('downloading circom to ', CIRCOM_INSTALLATION_PATH) + await downloadFile(CIRCOM_INSTALLATION_URL, CIRCOM_INSTALLATION_PATH) + console.log('downloading done') } catch (e) { console.error(e) } @@ -39,21 +76,17 @@ export const circomCli = { async isCircomInstalled () { try { - await execAsync(`circom --version`) - - return true + return existsSync(CIRCOM_INSTALLATION_PATH) } catch (e) { return false } }, - async isCargoInstalled () { - try { - await execAsync(`cargo version`) + async run (filePath: string, options?: Record) { + const cmd = `${CIRCOM_INSTALLATION_PATH} ${filePath} ${Object.keys(options || {}).map((key) => `--${key} ${options[key]}`).join(' ')}` + const { stdout, stderr } = await execAsync(cmd) - return true - } catch (e) { - return false - } + if (stderr) return console.error(stderr) + console.log(stdout) } } \ No newline at end of file