Skip to main content

Getting Started with the Sindri CLI

Build your first ZKP circuit with the Sindri CLI

The Sindri CLI provides a streamlined and intuitive way to access the Sindri platform's features. In this guide, we'll walk through the process of installing the Sindri CLI, verifying that it's working, and using it to create your first ZKP circuit on the Sindri platform. For a comprehensive overview of all available commands, refer to our CLI Reference Documentation.

Watch the entire process in the terminal recording below, or follow the detailed step-by-step guide that follows.

Loading terminal recording...

Install the Sindri CLI

The Sindri CLI is written in TypeScript and can be installed using npm with Node.JS v18 or later. We recommend that you use a node version manager such as nvm, fnm, n, or asdf to manage your node installation. This approach makes it easy to ensure that you have a recent version of node available and enables easy global installation of npm packages.

# Install or update the Sindri CLI to the latest version.
npm install -g sindri@latest

You can rerun the above command anytime to update the Sindri CLI to the latest version.

info

If you encounter an EACCES: permission denied error during installation, it signifies a misconfiguration in your Node.js environment for global package installations. To fix this, see Resolving EACCES permissions errors when installing packages globally.

Verify Your Installation

Verify the installation and version of the Sindri CLI by executing the sindri --version command.

# Check that the Sindri CLI is installed and using the latest version.
sindri --version
Command Output
v0.0.1-alpha.44

In case of an error message or an older version number, refer back to the steps in Install the Sindri CLI for troubleshooting.

Authenticate the Client

If you're a first-time user of the Sindri CLI, authenticate your Sindri account with the sindri login command. Follow the prompts to input your Sindri credentials, select the appropriate organization, and name the API key for CLI usage.

# Authenticate with your Sindri account.
sindri login
Command Output
? Username: my-username
? Password: ****************************
? New API Key Name: my-machine-cli
? Select an Organization: my-organization
[10:26:55.504] INFO: You have successfully authorized the client with your Sindri account.

This process saves your credentials in a local configuration file (e.g., ~/.config/sindri/sindri.conf.json on Linux) for future Sindri CLI commands. See sindri config for more information about interacting with this configuration file and its location on other operating systems.

Create Your Circuit

Use sindri init to easily create a new circuit project with your preferred framework. Pass your desired output directory as the first argument to sindri init, and answer the prompts to select the framework, curve, and any other options you'd like to use.

# Create a new circuit project.
sindri init my-circuit
Command Output
? Circuit Name: my-circuit
? Proving Framework: Circom
? Proving Scheme: Groth16
? Curve Name: BN254
? Witness Compiler: C++
[13:23:21.528] INFO: Proceeding to generate scaffolded project in "/private/tmp/my-circuit".
[13:23:21.548] INFO: Project scaffolding successful.
[13:23:21.719] INFO: Installing circomlib.
? Would you like to initialize a git repository in "/private/tmp/my-circuit"? yes
[13:23:23.921] INFO: Initializing git repository in "/private/tmp/my-circuit".
[13:23:24.061] INFO: Successfully initialized git repository.

This command creates a new directory, my-circuit in this example, and scaffolds a circuit project within it using your chosen framework and options. Regardless of the selected framework, the initial circuit accepts two variables, X and Y, and verifies their equality. You can use this as a starting point and customize it to implement your own circuit logic.

Check for Common Errors

Use the sindri lint command to check your circuit for common issues. Linting your circuit does not actually attempt to compile or run your circuit, but can quickly uncover common issues that would likely result in compilation or proving errors.

# The command must be run from within the circuit directory.
cd my-circuit

# Lint your circuit.
sindri lint
Command Output
[13:30:44.750] INFO: Sindri manifest file "/private/tmp/my-circuit/sindri.json" is valid.
[13:30:44.753] INFO: No issues found, good job!

Deploy Your Circuit

Compile and deploy your circuit with the sindri deploy command. This will upload a new version of your circuit to the Sindri platform, compile it, and make it available for interaction through the Sindri Website and for proving through the Sindri API.

# Deploy your circuit (from within the circuit directory).
sindri deploy
Command Output
[13:35:20.371] INFO: Creating "my-circuit.tar.gz" package with 151 files.
[13:35:20.439] INFO: Circuit compilation initiated.
[13:35:57.432] INFO: Circuit compiled successfully after 34.7 seconds.

Create a Proof

Generate a proof for your circuit with the sindri proof create command. This will create a new proof for your circuit and print out the proof, the verification key, and the public signals for the proof. Since we're passing the --verify flag here, the proof will also be verified after generation as a sanity check.

echo '{"X": 23, "Y": 23}' | sindri proof create --verify
Output - Proof Create
Command Output
{
"proofId": "896007f2-6ccb-47b5-9564-c338d3b37a6b",
"proof": {
"pi_a": [
"17364381172206213523720955259484553711705114748231509425057980791284185595002",
"18603770560571832882118846703693540077054221533489251076722101025665022884325",
"1"
],
"pi_b": [
[
"18008025325078629234845727794557593116563814468157046209774984169164967844877",
"3994153620708069716954195758241838430066162738347147717621199707618337517335"
],
[
"13373021319536170714282711951044553505934139969894171928386259905509392925002",
"9010928301196810271158827420321905801706821779775696992562796207069735069353"
],
["1", "0"]
],
"pi_c": [
"13448137022551307758155518302605816423908710504647574447652468181769026043575",
"12943874874293516922203458006621341356809187899792916960668664077131311586439",
"1"
],
"protocol": "groth16"
},
"public": ["1", "23"],
"verification_key": {
"protocol": "groth16",
"curve": "bn128",
"nPublic": 2,
"vk_alpha_1": [
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
"1"
],
"vk_beta_2": [
[
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
],
[
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
],
["1", "0"]
],
"vk_gamma_2": [
[
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
],
[
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
],
["1", "0"]
],
"vk_delta_2": [
[
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
],
[
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
],
["1", "0"]
],
"vk_alphabeta_12": [
[
[
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
],
[
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
],
[
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
]
],
[
[
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
],
[
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
],
[
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
]
]
],
"IC": [
[
"8730022663636478395875193122617326879937238221063249151534446790148472013425",
"11334276671345291957926027542189078543582133290479552018335938047376153562309",
"1"
],
[
"5805122324364949964217197833749490235941814633922129721750683970607503958245",
"9872725283256828335323531825525214004638956944986769896909638442373636094929",
"1"
],
[
"5965984761837059522598477963926636008539398000326611706501700041118398309075",
"987034796951392775354586470684197458011430956168601634143158925917302107696",
"1"
]
]
}
}

Next Steps

The Sindri CLI simplifies the creation, validation, and deployment of ZKP circuits in development. For production, consider using the Sindri API to generate proofs. You can do this in the programming language of your choice using the Sindri REST API, or you can use either the Sindri Python SDK or Sindri TypeScript SDK.