diff --git a/npm/cli.js b/npm/cli.js index 67c86e7f2..9f3e6df61 100755 --- a/npm/cli.js +++ b/npm/cli.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -const { CircomRunner, bindings } = require('./index') +const { CircomRunner } = require('./index') const fs = require('fs') const path = require('path') @@ -8,23 +8,13 @@ async function main() { let args = process.argv .slice(2) .map((k) => (k.startsWith('-') ? k : k.endsWith('/') ? path.resolve(k) + '/' : path.resolve(k))) - if (!(args.includes('-o') && args.includes('--output'))) + if (!(args.includes('-o') || args.includes('--output'))) args.push('-o', process.cwd() + '/') if (args.length === 0) args.push('--help') const circom = new CircomRunner({ args, env: process.env, preopens: {"/":"/"}, - bindings: { - ...bindings, - exit(code) { - process.exit(code) - }, - kill(signal) { - process.kill(process.pid, signal) - }, - fs, - }, }) const wasm_bytes = fs.readFileSync(require.resolve('./circom.wasm')) // There is a slight delay between this logging and the circom compiler version logging diff --git a/npm/index.js b/npm/index.js index aa9366f7e..e96054426 100644 --- a/npm/index.js +++ b/npm/index.js @@ -1,108 +1,34 @@ -const isTypedArray = require('is-typed-array') -const path = require('path-browserify') - -const { WASI, WASIExitError, WASIKillError } = require('./vendor/wasi') - -const baseNow = Math.floor((Date.now() - performance.now()) * 1e-3) - -function hrtime() { - let clocktime = performance.now() * 1e-3 - let seconds = Math.floor(clocktime) + baseNow - let nanoseconds = Math.floor((clocktime % 1) * 1e9) - // return BigInt(seconds) * BigInt(1e9) + BigInt(nanoseconds) - return seconds * 1e9 + nanoseconds -} - -function randomFillSync(buf, offset, size) { - if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') { - // Similar to the implementation of `randomfill` on npm - let uint = new Uint8Array(buf.buffer, offset, size) - crypto.getRandomValues(uint) - return buf - } else { - try { - // Try to load webcrypto in node - let crypto = require('crypto') - // TODO: Update to webcrypto in nodejs - return crypto.randomFillSync(buf, offset, size) - } catch { - // If an error occurs, fall back to the least secure version - // TODO: Should we throw instead since this would be a crazy old browser - // or nodejs built without crypto APIs - if (buf instanceof Uint8Array) { - for (let i = offset; i < offset + size; i++) { - buf[i] = Math.floor(Math.random() * 256) - } - } - return buf - } - } -} - -const defaultBindings = { - hrtime: hrtime, - exit(code) { - throw new WASIExitError(code) - }, - kill(signal) { - throw new WASIKillError(signal) - }, - randomFillSync: randomFillSync, - isTTY: () => true, - path: path, - fs: null, -} +const { WASI, WASIExitError } = require('wasi') +const fs = require('fs') +const os = require('node:os') const defaultPreopens = { '.': '.', } +const nullDescriptor = fs.openSync(os.devNull) + class CircomRunner { constructor({ args, env, preopens = defaultPreopens, - bindings = defaultBindings, quiet = false, } = {}) { - if (!bindings.fs) { - throw new Error('You must specify an `fs`-compatible API as part of bindings') - } this.wasi = new WASI({ + version: 'preview1', args: ['circom2', ...args], env, preopens, - bindings, - quiet, + stdout: quiet ? nullDescriptor : 1, + stderr: quiet ? nullDescriptor : 2, }) } - async compile(bufOrResponse) { - // TODO: Handle ArrayBuffer - if (isTypedArray(bufOrResponse)) { - return WebAssembly.compile(bufOrResponse) - } - - // Require Response object if not a TypedArray - const response = await bufOrResponse - if (!(response instanceof Response)) { - throw new Error('Expected TypedArray or Response object') - } - - const contentType = response.headers.get('Content-Type') || '' - - if ('instantiateStreaming' in WebAssembly && contentType.startsWith('application/wasm')) { - return WebAssembly.compileStreaming(response) - } - - const buffer = await response.arrayBuffer() - return WebAssembly.compile(buffer) - } - async execute(bufOrResponse) { - const mod = await this.compile(bufOrResponse) + const mod = await WebAssembly.compile(bufOrResponse) const instance = await WebAssembly.instantiate(mod, { - ...this.wasi.getImports(mod), + ...this.wasi.getImportObject(), }) try { @@ -124,4 +50,3 @@ class CircomRunner { module.exports.CircomRunner = CircomRunner module.exports.preopens = defaultPreopens -module.exports.bindings = defaultBindings diff --git a/npm/package-lock.json b/npm/package-lock.json index 69011565a..0738097f3 100644 --- a/npm/package-lock.json +++ b/npm/package-lock.json @@ -1,25 +1,28 @@ { "name": "@distributedlab/circom2", - "version": "0.2.18-rc.2", + "version": "0.2.18-rc.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@distributedlab/circom2", - "version": "0.2.18-rc.2", + "version": "0.2.18-rc.3", "license": "GPL-3.0", "dependencies": { "@wasmer/wasi": "^0.12.0", "is-typed-array": "^1.1.8", "path-browserify": "^1.0.1" }, + "bin": { + "circom2": "cli.js" + }, "devDependencies": { "@iden3/binfileutils": "^0.0.11", "prettier": "^2.5.1", "r1csfile": "^0.0.41" }, "engines": { - "node": ">=15" + "node": ">=16.3.0" }, "optionalDependencies": { "rustwasmc": "^0.1.29" diff --git a/npm/package.json b/npm/package.json index ff3094404..179154628 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "@distributedlab/circom2", - "version": "0.2.18-rc.2", + "version": "0.2.18-rc.3", "description": "Circom 2.0 in WebAssembly", "main": "index.js", "scripts": { @@ -9,8 +9,11 @@ "build-dev": "rustwasmc build --dev ../circom && cp ../circom/pkg/circom.wasm circom.wasm" }, "repository": "https://github.com/distributed-lab/circom-wasm", + "bin": { + "circom2": "./cli.js" + }, "engines": { - "node": ">=15" + "node": ">=16.3.0" }, "author": "Distributed Lab", "license": "GPL-3.0",