CLI Commands
The bonsol cli is a command line interface for interacting with bonsol programs, building, and deploying zk programs.
Required Software
Installation Instructions
These installation instructions may not be complete and may vary from system to system. These instuctions should work on MacOS and Linux instructions for Linux. If you are a windows user please open a pr and we will update these instructions and Godspeed brave soldier
# Install Rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Rust 1.79.0
rustup install 1.79.0
# Install Solana using solana-install
curl --proto '=https' --tlsv1.2 -sSf https://release.solana.com/v1.18.17/install | sh
# Install Anchor avm
cargo install --git https://github.com/project-serum/anchor avm --locked
# Install Anchor 0.30.1
avm install 0.30.1
# Install Bonsol CLI, Risc0 Toolchain
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/anagrambuild/bonsol/refs/master/composition/install.sh | sh
Don't forget to install the required dependencies for your system.
Installation
To install the bonsol cli you can use the following command.
cargo install bonsol-cli --git https://github.com/anagrambuild/bonsol
Usage
Required arguments for most commands
-c
or--config
: The path to the config file-k
or--keypair
: The path to the keypair file-u
or--rpc-url
: The url to the solana rpc
If you dont provide a keypair or rpc url or a config, the cli will use the default solana config file located in ~/.config/solana/
example:
bonsol -k ./keypair.json -u http://localhost:8899 ...
init
: Starting a new bonsol program
bonsol init nameofprogram
This command will create a new bonsol program in the current directory.
build
: Building a Bonsol Zk Program
With the Bonsol cli installed we can now build our zk program using the following command.
bonsol build -z ./path-to-your-program
This will create a manifest.json file in the root of your program directory. This manifest file contains all the information needed to deploy your program. Example manifest.json
{
"name": "simple",
"binaryPath": "images/simple/target/riscv-guest/riscv32im-risc0-zkvm-elf/docker/simple/simple",
"imageId": "20b9db715f989e3f57842787badafae101ce0b16202491bac1a3aebf573da0ba",
"inputOrder": [
"Public",
"Private"
],
"signature": "3mdQ6RUV5Bw9f1oUJhfif4GqVQpE8Udcu7ZR5NjDeyEx5ls2aRxD74DC5v1d251q6c9Q4m523a5a1h0nOO5f+s",
"size": 266608
}
If you run into any errors with the command you can check the CLI Errors section for more information.
deploy
: Deploying a Bonsol Zk Program
After building your zkprogram with "bonsol build ...", you can deploy it via the bonsol cli.
You have a few options for how you want to deploy: Manual S3 ShdwDrive
Manual
You can always upload your program anywhere on the internet as long as its publicly accessible by the relayer network. Bonsol is very strict that the size of the bytes must match the size expected from the onchain deployment record. Manual deployment can be a cause of bugs and mismatches in this regard so we dont reccomend it.
To deploy manually you can use the following command.
bonsol deploy -m ./path-to-your-manifest.json -t {s3|shadowdrive|manual}
S3
You can upload your program to s3 and have it be accessible by the relayer network. This is the recommended way to deploy your program.
bonsol deploy -m ./path-to-your-manifest.json -t s3 --access-key {your access key} --secret-key {your secret key}
ShadowDrive
ShadowDrive is a decentralized storage network that allows you to upload your program to a storage provider and have it be accessible by the relayer network. This is the recommended way to deploy your program.
If you have not already created a storage account you can create and upload in one command.
bonsol deploy -m ./path-to-your-manifest.json -t shadowdrive --storage-account-name {your storage account} --storage-account-size-mb {your storage account size in mb} --storage-account-name {your storage account name} --alternate-keypair {path to your alternate keypair}
Once you have created your storage account you can upload your program to it for the future versions of your program.
bonsol deploy -m ./path-to-your-manifest.json -t shadowdrive --storage-account {your storage account}
execute
: Requesting Execution
Being able to request a one off execution is a key feature of Bonsol. This allows you to prove computations that are impossible to run on-chain.
You can do this with the cli, using the bonsol execute
command.
bonsol execute -f execution-request.json
Since there are quite a few options for how you can request execution, the cli takes a json file as an argument. Here is an example of a valid execution request json file.
{
"imageId": "20b9db715f989e3f57842787badafae101ce0b16202491bac1a3aebf573da0ba",
"executionId": "9878798-987987-987987-987987",
"tip": 100,
"maxBlockHeight": 100,
"inputs": [
{
"inputType": "Public",
"data": "<base64 encoded data>"
}
],
"callbackConfig": {
"programId": "your program id",
"instructionPrefix": [0, 1, 2, 3],
"extraAccounts": [
{
"address": "",
"role": "writable"
}
]
},
"executionConfig": {
"verifyInputHash": true,
"forwardOutput": true,
"inputHash": "<hex encoded sha256 hash of the input data>" //sha256 hash of the input data if ommited the hash will be calculated
}
}
Many of the fields can be overriden with cli flags, the only required fields in the execution request json are
- "imageId"
- "executionConfig" And the only way to set a callback config is through the json file.
For example you can keep the execution file lightweight by using the cli flags. And make a input fule for changing inputs or even pipe the json into the command. Also if you omit the execution id the cli will generate a random one for you.
Waiting
If you pass the --wait
flag to the cli, the cli will wait for the execution to be completed and then return the result.
bonsol execute -f execution-request.json --wait
When a node claims the execution, the cli will notify you with a message.
Execution 9878798-987987-987987-987987 claimed by 6zT31kLCj8yM1RnJuiCbhHyybxsEGuvr8DP2biNi6j7o
The default timeout for the cli is to wait until the expiry block, you can change this with the --timeout
flag.
If execution is not completed within the timeout, the cli will return an message.
Error: Execution 9878798-987987-987987-987987 timed out
If the execution request expired without being claimed, the cli will return an message.
Error: Execution 9878798-987987-987987-987987 expired
When everything is successful, the cli will return the result of the execution.
Execution 9878798-987987-987987-987987 completed successfully
prove
: Local Proving with the CLI
Local proving is a key feature of Bonsol. This allows you to prove computations that are impossible to run on-chain.
You can do this with the cli, using the bonsol prove
command. In this scenario you will need to be proving against a deployed program.
bonsol prove -f local.json -e <execution_id> -m <manifest_path> | -i <image_id>
Similar to the bonsol execute
command, the cli takes a json file as an argument.
Here is an example of a valid local proving payload json file.
{
"imageId": "20b9db715f989e3f57842787badafae101ce0b16202491bac1a3aebf573da0ba",
"inputs": [
{
"inputType": "PrivateLocal",
"data": "<base64 encoded data>"
}
]
}
You can also pipe the inputs in like so
echo '"{"attestation":"test"}" "nottest"' | bonsol prove -e <execution_id> -m images/simple/manifest.json
Only private local inputs are supported
Output
If proving succeeds, the cli will return a serialized risc0 reciept. This is a binary format.
the cli will save a file called <execution_id>.bin
in the current directory or the directory specified with the --output-dir <dir>
flag.
For more on how to use Proof Composition in Bonsol, check out the Proof Composition guide.