circuitscan
Advanced tools
Comparing version
51
cli.js
#!/usr/bin/env node | ||
import {Command} from 'commander'; | ||
import {verify, deploy, verifyMulti} from './index.js'; | ||
import { | ||
instanceSizes, | ||
getPackageJson, | ||
formatBytes, | ||
MAX_POST_SIZE, | ||
DEFAULT_CONFIG, | ||
} from './src/utils.js'; | ||
import circomCommands from './src/circom/index.js'; | ||
import circomMultiCommands from './src/circomMulti/index.js'; | ||
const program = new Command(); | ||
program | ||
.name('circuitscan') | ||
.description('CLI tool to verify verifier contracts by their circom sources') | ||
.version(getPackageJson().version); | ||
.name('circuitscan') | ||
.description('CLI tool to verify verifier contracts by their circom sources') | ||
.version(getPackageJson().version); | ||
program | ||
.command('verify:circom <mainCircomFile> <chainId> <verifierContractAddress>') | ||
.description('Verify verifier contracts by their circom sources. Can also specify chain by name.') | ||
.option('-p, --protocol <protocol>', 'Specify the protocol: groth16 (default), fflonk, plonk (overrides circomkit.json if available)') | ||
.option('-k, --proving-key <provingKey>', `Specify the proving key filename or url (optional, for Groth16 trusted setups). Must be https hosted if >${formatBytes(MAX_POST_SIZE)}`) | ||
.option('-t, --ptau <ptauSize>', 'Force a specific Powers of Tau size (8-28 or url to download specific file)') | ||
.option('-v, --circom-version <circomVersion>', 'Specify the Circom version (e.g. "v2.1.8")') | ||
.option('-s, --snarkjs-version <snarkjsVersion>', 'Specify the SnarkJS version (e.g. "0.7.3")') | ||
.option('-i, --instance <memorySize>', `Specify the memory (GB) of compiler instance: ${Object.keys(instanceSizes).join(', ')} (default: 10GB lambda, faster init for small circuits)`) | ||
.option('-r, --resume <requestId>', 'In case of errors during compilation, reattach to a job and attempt a new deploy. Overrides all other options.') | ||
.option('-c, --config <configUrl>', `Specify a different configuration file (default: ${DEFAULT_CONFIG})`) | ||
.option('-a, --api-key <apiKey>', `Specify your API Key as a command line argument`) | ||
.action(verify); | ||
// Each pipeline adds its commands | ||
circomCommands(program); | ||
circomMultiCommands(program); | ||
program | ||
.command('deploy:circom <mainCircomFile> [chainId]') | ||
.description('Deploy verifier contract by their circom sources. Can also specify chain by name.') | ||
.option('-p, --protocol <protocol>', 'Specify the protocol: groth16 (default), fflonk, plonk (overrides circomkit.json if available)') | ||
.option('-k, --proving-key <provingKey>', `Specify the proving key filename or url (optional, for Groth16 trusted setups). Must be https hosted if >${formatBytes(MAX_POST_SIZE)}`) | ||
.option('-t, --ptau <ptauSize>', 'Force a specific Powers of Tau size (8-28 or url to download specific file)') | ||
.option('-v, --circom-version <circomVersion>', 'Specify the Circom version (e.g. "v2.1.8")') | ||
.option('-s, --snarkjs-version <snarkjsVersion>', 'Specify the SnarkJS version (e.g. "0.7.3")') | ||
.option('-i, --instance <memorySize>', `Specify the memory (GB) of compiler instance: ${Object.keys(instanceSizes).join(', ')} (default: 10GB lambda, faster init for small circuits)`) | ||
.option('-r, --resume <requestId>', 'In case of errors during compilation, reattach to a job and attempt a new deploy. Overrides all other options.') | ||
.option('-c, --config <configUrl>', `Specify a different configuration file (default: ${DEFAULT_CONFIG})`) | ||
.option('-a, --api-key <apiKey>', `Specify your API Key as a command line argument`) | ||
.option('-b, --browser-wallet', 'Send transaction in browser instead of by passing private key env var (overrides chainId argument)') | ||
.action(deploy); | ||
program | ||
.command('verify:circom-multi <jsonFile>') | ||
.description('Verify a Groth16 multi-verifier using a JSON specification. See docs website for details.') | ||
.option('-c, --config <configUrl>', `Specify a different configuration file (default: ${DEFAULT_CONFIG})`) | ||
.action(verifyMulti); | ||
program.parse(process.argv); |
{ | ||
"name": "circuitscan", | ||
"version": "0.0.25-alpha", | ||
"main": "index.js", | ||
"version": "0.0.26-alpha", | ||
"main": "cli.js", | ||
"type": "module", | ||
@@ -6,0 +6,0 @@ "author": "numtel <ben@latenightsketches.com>", |
@@ -5,6 +5,8 @@ # Circuitscan CLI | ||
See also: [Circuitscan CLI Documentation](https://circuitscan.readthedocs.io/en/latest/usage.html) | ||
> [!NOTE] | ||
> Very much still under construction! | ||
> | ||
> Supports circom 2.0.8-2.1.8, snarkjs 0.6.11-0.7.4 | ||
> Supports circom 2.0.8-2.1.9, snarkjs 0.6.11-0.7.4 | ||
@@ -11,0 +13,0 @@ |
@@ -1,8 +0,12 @@ | ||
import {accessSync, readFileSync, appendFileSync} from 'node:fs'; | ||
import {accessSync, readFileSync} from 'node:fs'; | ||
import {dirname, join, resolve} from 'node:path'; | ||
import {homedir} from 'node:os'; | ||
import {fileURLToPath} from 'node:url'; | ||
import * as chains from 'viem/chains'; | ||
export const DEFAULT_CONFIG = 'https://circuitscan.org/cli.json'; | ||
export const MAX_POST_SIZE = 6 * 1024 ** 2; // 6 MB | ||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
export async function loadConfig(options) { | ||
@@ -20,37 +24,4 @@ options.instance = options.instance || '4'; | ||
export function appendRequest(reqId) { | ||
appendFileSync(join(homedir(), '.circuitscan-history'), `${reqId}\n`); | ||
} | ||
function loadUserConfig() { | ||
try { | ||
return JSON.parse(readFileSync(join(homedir(), '.circuitscan'), 'utf8')); | ||
} catch(error) { | ||
console.error(error); | ||
process.exit(1); | ||
} | ||
} | ||
export function activeApiKey(options) { | ||
if(options.apiKey) return options.apiKey; | ||
if(process.env.CIRCUITSCAN_API_KEY) return process.env.CIRCUITSCAN_API_KEY; | ||
const config = loadUserConfig() || {}; | ||
return config.apiKey; | ||
} | ||
export function prepareProvingKey(input) { | ||
// Not specified | ||
if(!input) return undefined; | ||
// Externally hosted | ||
if(typeof input === 'string' && input.startsWith('https')) return input; | ||
const output = readFileSync(input).toString('base64'); | ||
if(output.length > MAX_POST_SIZE) | ||
throw new Error(`Proving key too large for inline upload. (Max ${formatBytes(MAX_POST_SIZE)}) Host on https server instead.`); | ||
// Send inline | ||
return output; | ||
} | ||
export function getPackageJson() { | ||
return JSON.parse(readFileSync('./package.json', 'utf8')); | ||
return JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8')); | ||
} | ||
@@ -144,1 +115,10 @@ | ||
} | ||
export function viemChain(nameOrId) { | ||
if(isNaN(nameOrId)) { | ||
return chains[nameOrId]; | ||
} | ||
for(let chain of chains) { | ||
if(chain.id === Number(nameOrId)) return chain; | ||
} | ||
} |
import {deepStrictEqual, strictEqual, ok} from 'node:assert'; | ||
import loadCircom from '../src/loadCircom.js'; | ||
import loadCircom from '../src/circom/loadSources.js'; | ||
const circomkitRootDir = 'test/circuits/circomkit/'; | ||
const vanillaRootDir = 'test/circuits/vanilla/src/'; | ||
describe('loadCircom', function() { | ||
it('should load circomkit.json includes from same dir', function() { | ||
const file = 'test/circuits/circomkit/mainB.circom'; | ||
const loaded = loadCircom(file); | ||
const file = 'mainB.circom'; | ||
const sources = loadCircom(circomkitRootDir + file); | ||
const loaded = sources.files; | ||
const firstKey = Object.keys(loaded)[0]; | ||
@@ -22,4 +26,5 @@ strictEqual(firstKey, file); | ||
it('should load circomkit.json includes from parent dir', function() { | ||
const file = 'test/circuits/circomkit/src/mainA.circom'; | ||
const loaded = loadCircom(file); | ||
const file = 'src/mainA.circom'; | ||
const sources = loadCircom(circomkitRootDir + file); | ||
const loaded = sources.files; | ||
const firstKey = Object.keys(loaded)[0]; | ||
@@ -39,6 +44,6 @@ strictEqual(firstKey, file); | ||
it('should fail when not found', function() { | ||
const file = 'test/circuits/circomkit/src/mainC.circom'; | ||
const file = 'src/mainC.circom'; | ||
let hadError; | ||
try { | ||
const loaded = loadCircom(file); | ||
const loaded = loadCircom(circomkitRootDir + file); | ||
} catch(error) { | ||
@@ -52,4 +57,5 @@ hadError = true; | ||
it('should load from circomlib without circomkit.json', function() { | ||
const file = 'test/circuits/vanilla/src/mainC.circom'; | ||
const loaded = loadCircom(file); | ||
const file = 'mainC.circom'; | ||
const sources = loadCircom(vanillaRootDir + file); | ||
const loaded = sources.files; | ||
const firstKey = Object.keys(loaded)[0]; | ||
@@ -56,0 +62,0 @@ strictEqual(firstKey, file); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
26
4%1174
7.02%166
1.22%53742
-38.03%12
9.09%