# @jayanth-kumar-morem/snarkjs-to-solana

A comprehensive toolkit for converting snarkjs artifacts to Solana-compatible formats. This package provides both CLI tools and programmatic APIs for converting zero-knowledge proofs and verification keys from snarkjs to formats that work with Solana's groth16 verifier.

## Features

- **Triple-target WASM compilation**: Optimized for web, bundler, and Node.js/CommonJS environments
- **CLI interface**: Convert verification keys directly from the command line
- **Programmatic API**: Integrate proof conversion into your applications
- **Automatic environment detection**: Seamlessly works in Node.js, browsers, and bundlers
- **TypeScript support**: Full type definitions included
- **CommonJS and ESM compatibility**: Works with both module systems

## Installation

### Global Installation (Recommended for CLI usage)
```bash
npm install -g @jayanth-kumar-morem/snarkjs-to-solana
```

### Local Installation
```bash
npm install @jayanth-kumar-morem/snarkjs-to-solana
```

If installed locally, you can run CLI commands using `npx`:
```bash
npx snarkjs-to-solana verification-key-to-rust verification_key.json
```

## CLI Usage

### Convert Verification Key to Rust

Convert a snarkjs verification key JSON file to a Rust file compatible with Solana's groth16 verifier.

**Usage:**
```bash
snarkjs-to-solana verification-key-to-rust <verification-key-path> [options]
```

**Arguments:**
- `<verification-key-path>`: Path to the verification key JSON file generated by snarkjs

**Options:**
- `-o, --output <directory>`: Output directory (defaults to current directory)
- `-h, --help`: Display help for the command

**Examples:**
```bash
# Convert verification key to current directory
snarkjs-to-solana verification-key-to-rust verification_key.json

# Convert verification key to specific directory
snarkjs-to-solana verification-key-to-rust verification_key.json --output ./rust_files

# Short form
snarkjs-to-solana verification-key-to-rust verification_key.json -o ./rust_files

# Show help
snarkjs-to-solana verification-key-to-rust --help
```

**Output:**
The command generates a `verifying_key.rs` file containing:
- A Rust struct compatible with `groth16_solana::groth16::Groth16Verifyingkey`
- All verification key parameters properly formatted for Solana
- Ready-to-use constants for your Solana verification program

## Programmatic Usage

### Node.js / CommonJS Environment

```javascript
// Works with both CommonJS (require) and ESM (import) in Node.js
const { getSolanaCompatibleProof } = require('@jayanth-kumar-morem/snarkjs-to-solana');
// OR
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana';

// This automatically uses the Node.js-targeted WASM package (CommonJS compatible)
const result = await getSolanaCompatibleProof(proof);
```

### Modern Bundler Environment (Webpack, Vite, etc.)

```javascript
// In bundler environments like Webpack, Vite, Rollup, etc.
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana';

// This automatically uses the bundler-targeted WASM package
const result = await getSolanaCompatibleProof(proof);
```

### Browser Environment

```javascript
// In a browser environment, the package automatically uses the web-targeted WASM
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana';

// This automatically uses the web-targeted WASM package
const result = await getSolanaCompatibleProof(proof);
```

### Manual Target Selection

```javascript
// If you need to explicitly control which target to use:

// For bundler environments (Node.js, Webpack, Vite, etc.)
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana/dist/index.js';

// For web environments (browsers)
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana/dist/index.browser.js';
```

## Complete Example

Here's a full example showing how to generate proofs with snarkjs and convert them for Solana:

```javascript
import * as snarkjs from "snarkjs";
import { getSolanaCompatibleProof } from '@jayanth-kumar-morem/snarkjs-to-solana';

// 1. Generate proof using snarkjs
const {proof: circuitProof, publicSignals} = await snarkjs.groth16.fullProve(
    circuitInputs,
    "../circom/ethDepositProof_js/ethDepositProof.wasm",
    "../circom/ethDepositProof_js/1_0000.zkey",
);

// 2. Convert proof to Solana-compatible format
const {proofA, proofB, proofC} = await getSolanaCompatibleProof(circuitProof);

// 3. Use proofA, proofB, proofC in your Solana on-chain instruction
// These can now be passed to your Solana program for verification
```

## Integration with snarkjs Workflow

1. **Generate your circuit and verification key with snarkjs:**
   ```bash
   snarkjs groth16 setup circuit.r1cs powersOfTau28_hez_final_10.ptau circuit_0000.zkey
   snarkjs zkey export verificationkey circuit_0000.zkey verification_key.json
   ```

2. **Convert verification key to Rust format:**
   ```bash
   snarkjs-to-solana verification-key-to-rust verification_key.json
   ```

3. **Generate and convert proofs in your application:**
   ```javascript
   // Generate proof with snarkjs
   const {proof: circuitProof, publicSignals} = await snarkjs.groth16.fullProve(
       circuitInputs,
       "circuit.wasm",
       "circuit.zkey"
   );
   
   // Convert for Solana
   const {proofA, proofB, proofC} = await getSolanaCompatibleProof(circuitProof);
   ```

4. **Use in your Solana program:**
   ```rust
   use groth16_solana::groth16::Groth16Verifyingkey;
   
   // Include the generated verification key file
   mod verifying_key;
   use verifying_key::VERIFYINGKEY;
   
   // Verify the proof on-chain
   groth16_solana::groth16::verify(&VERIFYINGKEY, &proof, &public_inputs)?;
   ```

5. **Call Solana on-chain instruction with converted proofs:**
   The `proofA`, `proofB`, and `proofC` values from step 3 are passed to your Solana program instruction for on-chain verification.

## How It Works

The package automatically detects the environment and loads the appropriate WASM target:

- **Bundler Target**: Optimized for Node.js and bundler environments (Webpack, Vite, Rollup, etc.)
- **Web Target**: Optimized for direct browser usage with proper ES6 module support

The conditional exports in `package.json` ensure that:
- Modern bundlers get the bundler-optimized version
- Browsers get the web-optimized version
- The appropriate WASM files are loaded dynamically

## Build Process

The package uses a dual-target build system:

1. **WASM Compilation**: Rust code is compiled to two WASM targets using `wasm-pack`
2. **Unified Package**: Both targets are combined into a single package structure
3. **Conditional Exports**: Package.json exports map environments to appropriate entry points
4. **TypeScript Compilation**: TypeScript code is compiled to JavaScript for both targets

## Error Handling

The CLI provides clear error messages for common issues:

- **File not found**: If the verification key file doesn't exist
- **Invalid JSON**: If the verification key file is not valid JSON
- **Parse errors**: If the verification key format is not compatible with ffjavascript
- **Permission errors**: If the output directory cannot be written to

## Troubleshooting

### CommonJS/ESM Compatibility Issues

If you encounter module loading errors in Node.js:

```javascript
// Try using require for CommonJS environments
const { getSolanaCompatibleProof } = require('@jayanth-kumar-morem/snarkjs-to-solana');

// Or dynamic import for ESM environments
const { getSolanaCompatibleProof } = await import('@jayanth-kumar-morem/snarkjs-to-solana');
```

### Command not found
If you get "command not found" error:
1. Ensure the package is installed globally: `npm install -g @jayanth-kumar-morem/snarkjs-to-solana`
2. Or use with npx: `npx @jayanth-kumar-morem/snarkjs-to-solana`

### Permission denied
If you get permission errors:
1. Check that you have write permissions to the output directory
2. Try specifying a different output directory with `-o`

### Invalid verification key format
Ensure your verification key was generated by snarkjs and follows the expected format:
```json
{
  "vk_alpha_1": [...],
  "vk_beta_2": [...],
  "vk_gamma_2": [...],
  "vk_delta_2": [...],
  "IC": [...]
}
```

## Package Structure

```
proof_utils/
├── pkg/
│   ├── web/           # Web-targeted WASM files
│   ├── bundler/       # Bundler-targeted WASM files
│   ├── index.js       # Main entry point (bundler)
│   ├── index-web.js   # Web entry point
│   └── package.json   # Unified package configuration
├── src/
│   ├── index.ts       # Main TypeScript entry (bundler)
│   └── index.browser.ts # Browser TypeScript entry (web)
└── dist/
    ├── index.js       # Compiled bundler version
    └── index.browser.js # Compiled web version
```

## API Reference

### `getSolanaCompatibleProof(proof: any): Promise<object>`

Converts a snarkjs proof to Solana-compatible format.

**Parameters:**
- `proof`: A proof object generated by snarkjs

**Returns:**
- Promise resolving to an object with `proofA`, `proofB`, and `proofC` properties

## Dependencies

- `ffjavascript`: For handling finite field arithmetic and proof parsing
- `commander`: For CLI argument parsing
- Custom WASM module for proof conversion

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Keywords

- convert-snarkjs-proof
- snarkjs-proof-convert
- groth16-proof-convert
- solana-verifier
- verification-key-to-rust
- cryptography
- zero-knowledge
- zk-proofs
- blockchain
