Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

circuitscan

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

circuitscan - npm Package Compare versions

Comparing version 0.0.2-alpha to 0.0.3-alpha

latest.json

12

cli.js
#!/usr/bin/env node
import {Command} from 'commander';
import {verify} from './index.js';
import {verify, deploy} from './index.js';

@@ -23,4 +23,12 @@ const program = new Command();

// TODO command to deploy a circuit verifier, verify its contract and circuit
program
.command('deploy <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 url (optional, for Groth16 trusted setups)')
.option('-v, --circom-version <circomVersion>', 'Specify the Circom version (e.g. "v2.1.8")')
.option('-i, --instance <memorySize>', 'Specify the memory (GB) of compiler instance: 4 for testing (default: 10GB lambda, faster init for small circuits)')
.option('-l, --localhost <localPort>', 'Use a circom compiler container running on a specific port')
.action(deploy);
program.parse(process.argv);
import {relative, dirname} from 'node:path';
import { isHex } from 'viem';
import loadCircom from './src/loadCircom.js';
import {findChainByName} from './src/chains.js';
import {findChain} from './src/chains.js';
import {generateRandomString, fetchJson, delay, instanceSizes} from './src/utils.js';
import {StatusLogger} from './src/StatusLogger.js';
import {
compileContract,
deployContract,
verifyOnEtherscan,
checkEtherscanStatus,
} from './src/deployer.js';

@@ -12,11 +19,62 @@ const defaultCircomPath = 'circom-v2.1.8';

const circomCompilerURL = 'https://uvopzbfbfz5i5m4i3tsgq7rjeu0glwdl.lambda-url.us-west-2.on.aws/';
const statusURL = 'https://blob.circuitscan.org/status/';
const stackStarterURL = 'https://fydvjclemuhxdzsv2treynl32q0rwtpp.lambda-url.us-west-2.on.aws/';
const blobUrl = 'https://blob.circuitscan.org/';
export async function verify(file, chainId, contractAddr, options) {
if(isNaN(chainId)) {
const chain = findChainByName(chainId);
if(!chain) throw new Error('invalid_chain');
chainId = chain.chain.id;
const chain = findChain(chainId);
if(!chain) throw new Error('invalid_chain');
const {curCompilerURL, stackId} = await determineCompilerUrl(options);
try {
const compiled = await compileFile(file, options, { curCompilerURL });
await verifyCircuit(compiled.pkgName, chain.chain.id, contractAddr, options);
} catch(error) {
console.error(error);
}
if(stackId) {
await stopInstance(stackId);
}
}
export async function deploy(file, chainId, options) {
const chain = findChain(chainId);
if(!chain) throw new Error('invalid_chain');
const privateKey = process.env.DEPLOYER_PRIVATE_KEY;
if(!privateKey || !isHex(privateKey) || privateKey.length !== 66)
throw new Error('INVALID_DEPLOYER_PRIVATE_KEY')
if(!(chain.apiKeyEnvVar in process.env))
throw new Error('MISSING_' + chain.apiKeyEnvVar);
const {curCompilerURL, stackId} = await determineCompilerUrl(options);
let instanceRunning = !!stackId;
try {
const compiled = await compileFile(file, options, { curCompilerURL });
if(stackId) {
await stopInstance(stackId);
instanceRunning = false;
}
const contractSource = await (await fetch(`${blobUrl}${compiled.pkgName}/verifier.sol`)).text();
const solcOutput = compileContract(contractSource);
const contractAddress = await deployContract(solcOutput, chain.chain, privateKey);
let verifyResult = false;
while(!verifyResult || verifyResult.result.startsWith('Unable to locate ContractCode')) {
await delay(5000);
verifyResult = await verifyOnEtherscan(chain, contractAddress, contractSource, solcOutput.version);
}
if(!verifyResult.status === '1') throw new Error('UNABLE_TO_VERIFY_CONTRACT');
let contractStatus = {};
console.log(`# Waiting for verification on Etherscan...`);
while(['Already Verified', 'Pass - Verified'].indexOf(contractStatus.result) === -1) {
await delay(5000);
contractStatus = await checkEtherscanStatus(chain, verifyResult.result);
console.log(`> ${contractStatus.result}`);
}
await verifyCircuit(compiled.pkgName, chain.chain.id, contractAddress, options);
} catch(error) {
console.error(error);
}
if(stackId && instanceRunning) {
await stopInstance(stackId);
}
}
async function determineCompilerUrl(options) {
let curCompilerURL = circomCompilerURL;

@@ -31,12 +89,3 @@ let stackId;

}
const compiled = await compileFile(file, options, { curCompilerURL });
const verified = await verifyCircuit(compiled.pkgName, chainId, contractAddr, options);
if(verified && verified.status === 'verified') {
console.log(`# Completed successfully!`);
} else {
console.log(`# Verification failed.`);
}
if(stackId) {
await stopInstance(stackId);
}
return {curCompilerURL, stackId};
}

@@ -125,3 +174,3 @@

// status report during compilation
const status = new StatusLogger(`${statusURL}${requestId}.json`, 3000);
const status = new StatusLogger(`${blobUrl}status/${requestId}.json`, 3000);

@@ -198,2 +247,8 @@ const event = {

if(body && body.status === 'verified') {
console.log(`# Completed successfully!`);
console.log(`\nhttps://circuitscan.org/chain/${chainId}/address/${contractAddr}`);
} else {
console.log(`# Verification failed.`);
}
return body;

@@ -200,0 +255,0 @@ }

3

package.json
{
"name": "circuitscan",
"version": "0.0.2-alpha",
"version": "0.0.3-alpha",
"main": "index.js",

@@ -25,4 +25,5 @@ "type": "module",

"commander": "^12.0.0",
"solc": "^0.8.26",
"viem": "^2.12.5"
}
}

@@ -74,6 +74,58 @@ # Circuitscan CLI

NYI!
```
Usage: circuitscan deploy [options] <mainCircomFile> <chainId>
Deploy verifier contract by their circom sources. Can also specify chain by name.
Options:
-p, --protocol <protocol> Specify the protocol: groth16 (default), fflonk, plonk (overrides circomkit.json if available)
-k, --proving-key <provingKey> Specify the proving key url (optional, for Groth16 trusted setups)
-v, --circom-version <circomVersion> Specify the Circom version (e.g. "v2.1.8")
-i, --instance <memorySize> Specify the memory (GB) of compiler instance: 4 for testing (default: 10GB lambda, faster init for small circuits)
-l, --localhost <localPort> Use a circom compiler container running on a specific port
-h, --help display help for command
```
> [!IMPORTANT]
> `DEPLOYER_PRIVATE_KEY` environment variable and a corresponding Etherscan API key is required
| name | apiKeyEnvVar |
|--------------|---------------------------|
| holesky | ETHERSCAN_API_KEY |
| sepolia | ETHERSCAN_API_KEY |
| mainnet | ETHERSCAN_API_KEY |
| optimism | OPTIMISM_ETHERSCAN_API_KEY|
| polygon | POLYGON_ETHERSCAN_API_KEY |
| fantom | FANTOM_ETHERSCAN_API_KEY |
| arbitrum | ARBITRUM_ETHERSCAN_API_KEY|
| arbitrumNova | ARBITRUM_NOVA_ETHERSCAN_API_KEY|
| gnosis | GNOSIS_ETHERSCAN_API_KEY |
| celo | CELO_ETHERSCAN_API_KEY |
| base | BASE_ETHERSCAN_API_KEY |
Example usage using `.env` for configuration:
```
$ dotenv run circuitscan deploy circuits/multiplier.circom polygon
Found 1 file(s):
multiplier.circom
> Compiling multiplier-worried-aqua-roundworm...
> Downloading PTAU... @ 0.0207s
> Groth16 setup with random entropy... @ 0.0211s
> Exporting verification key and solidity verifier... @ 0.0676s
> Storing build artifacts... @ 0.0860s
# Sent transaction 0x5b208fa766f744840fcf3827b7f2573f2ab1ec03c200c294dd6c73c98c6108f2
# Deployed to 0x269e831b930f4c1ec7eee28aa53e5756b0f96d0c
# Waiting for verification on Etherscan...
> Pass - Verified
# Verifying circuit...
# Completed successfully!
https://circuitscan.org/chain/137/address/0x269e831b930f4c1ec7eee28aa53e5756b0f96d0c
```
## License
MIT

@@ -16,2 +16,5 @@ import {

export function findChain(chainId) {
if(isNaN(chainId)) {
return findChainByName(chainId);
}
for(let chain of chains) {

@@ -22,3 +25,3 @@ if(Number(chainId) === chain.chain.id) return chain;

export function findChainByName(name) {
function findChainByName(name) {
for(let chain of chains) {

@@ -29,3 +32,2 @@ if(name === chain.name) return chain;

export const chains = [

@@ -36,3 +38,4 @@ {

apiUrl: 'https://api-holesky.etherscan.io/api',
apiKey: process.env.ETHERSCAN_API_KEY
apiKey: process.env.ETHERSCAN_API_KEY,
apiKeyEnvVar: 'ETHERSCAN_API_KEY'
},

@@ -43,3 +46,4 @@ {

apiUrl: 'https://api-sepolia.etherscan.io/api',
apiKey: process.env.ETHERSCAN_API_KEY
apiKey: process.env.ETHERSCAN_API_KEY,
apiKeyEnvVar: 'ETHERSCAN_API_KEY'
},

@@ -50,3 +54,4 @@ {

apiUrl: 'https://api.etherscan.io/api',
apiKey: process.env.ETHERSCAN_API_KEY
apiKey: process.env.ETHERSCAN_API_KEY,
apiKeyEnvVar: 'ETHERSCAN_API_KEY'
},

@@ -57,3 +62,4 @@ {

apiUrl: 'https://api-optimistic.etherscan.io/api',
apiKey: process.env.OPTIMISM_ETHERSCAN_API_KEY
apiKey: process.env.OPTIMISM_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'OPTIMISM_ETHERSCAN_API_KEY'
},

@@ -64,3 +70,4 @@ {

apiUrl: 'https://api.polygonscan.com/api',
apiKey: process.env.POLYGON_ETHERSCAN_API_KEY
apiKey: process.env.POLYGON_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'POLYGON_ETHERSCAN_API_KEY'
},

@@ -71,3 +78,4 @@ {

apiUrl: 'https://api.ftmscan.com/api',
apiKey: process.env.FANTOM_ETHERSCAN_API_KEY
apiKey: process.env.FANTOM_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'FANTOM_ETHERSCAN_API_KEY'
},

@@ -78,3 +86,4 @@ {

apiUrl: 'https://api.arbiscan.io/api',
apiKey: process.env.ARBITRUM_ETHERSCAN_API_KEY
apiKey: process.env.ARBITRUM_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'ARBITRUM_ETHERSCAN_API_KEY'
},

@@ -85,3 +94,4 @@ {

apiUrl: 'https://api.arbiscan.io/api',
apiKey: process.env.ARBITRUM_NOVA_ETHERSCAN_API_KEY
apiKey: process.env.ARBITRUM_NOVA_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'ARBITRUM_NOVA_ETHERSCAN_API_KEY'
},

@@ -92,3 +102,4 @@ {

apiUrl: 'https://api.gnosisscan.io/api',
apiKey: process.env.GNOSIS_ETHERSCAN_API_KEY
apiKey: process.env.GNOSIS_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'GNOSIS_ETHERSCAN_API_KEY'
},

@@ -99,3 +110,4 @@ {

apiUrl: 'https://api.celoscan.io/api',
apiKey: process.env.CELO_ETHERSCAN_API_KEY
apiKey: process.env.CELO_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'CELO_ETHERSCAN_API_KEY'
},

@@ -106,4 +118,6 @@ {

apiUrl: 'https://api.basescan.org/api',
apiKey: process.env.BASE_ETHERSCAN_API_KEY
apiKey: process.env.BASE_ETHERSCAN_API_KEY,
apiKeyEnvVar: 'BASE_ETHERSCAN_API_KEY'
},
];
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc