Bonsol Calculator Example
Building a Calculator DApp with Bonsol CLI
A zero-knowledge calculator web application using the Bonsol ZK network for verifiable computations. This guide walks you through building a simple calculator dApp using the Bonsol CLI and local development environment.
Here’s a link to the repo:
General flow
The general flow of the process that we’ll be covering can be visualized below:
React Frontend ──→ Express API ──→ Bonsol Network ──→ ZK Computation
↓ ↓ ↓ ↓
localhost:3000 localhost:3001 ZK Execution Verified Result
The proving system we use is the Groth16 SNARK that enables fast on-chain verification of proofs.
Prerequisites
Make sure you have the following installed:
Bonsol CLI - follow the steps in the installation guide to get started
Node.js (v18+ recommended)
Step 1: Set Up a Project
Firstly, we need to verify your installation
bonsol --version
The current version is Version 0.4.5
Create a New Project Directory:
mkdir bonsol-calculator
cd bonsol-calculator
Clone the repository
git clone <https://github.com/en-tropyc/bonsol-calculator.git>
We should see the following project structure:
bonsol_calculator/
├── bonsol
├── calculator-api
├── client
├── frontend
├── local-server
├── solana-program
├── zk-program
├── Cargo.toml
├── README.md
Step 2: Setting up the Local environment
The documentation here provides instructions for setting up a local Bonsol development environment for the calculator example.
<aside> <img src="/icons/activity_pink.svg" alt="/icons/activity_pink.svg" width="40px" />
At present, provers can only run on x86_64-linux systems due to dependencies in the STARK-to-SNARK tooling. We’re actively exploring macOS support, but in the meantime, we recommend using a remote Linux environment for development.
</aside>
In this step, you will need to
Start the Local Validator
The validator script builds and deploys the necessary Solana programs, including the Bonsol core program and an example callback program
./bin/validator.sh -r
If the validator fails to start, ensure that Rust and Solana CLI tools are properly installed
Run the Bonsol Prover Node
The prover node processes the off-chain computation. Open a new terminal and run:
$ ./bin/run-node.sh
Run the Local ZK Program Server
Provers on the network need to fetch the ZK programs and the input data used to generate the proof.
Open a new terminal and run:
$ cargo run -p local-zk-program-server
Step 3: The ZK Program
In zk-program/src/main.rs
Let's go through the code snippet:
// Calculator ZK program (from zk-program/manifest.json)
const CALCULATOR_IMAGE_ID: &str = "5881e972d41fe651c2989c65699528da8b1ed68ab7057350a686b8a64a00fc91";
const CALLBACK_PROGRAM_ID: &str = "2zBRw2sEXvjskx7w1w9hqdFEMZWy7KipQ6jKPfwjpnL6";
// Calculator operation codes (from zk-program/src/main.rs)
const OP_ADD: i64 = 0;
const OP_SUBTRACT: i64 = 1;
const OP_MULTIPLY: i64 = 2;
const OP_DIVIDE: i64 = 3;
Constants - The program defines four operation codes as u8 values:
OP_ADD (0): Addition.
OP_SUBTRACT (1): Subtraction.
OP_MULTIPLY (2): Multiplication.
OP_DIVIDE (3): Division.
These constants serve as identifiers for the different arithmetic operations the program is designed to handle. By mapping each operation to a distinct u8
value, the program can efficiently reference and execute these operations based on their numeric codes.
Input Format
The calculator ZK program expects three inputs as i64 little-endian bytes:
Operation Code (8 bytes): 0=add, 1=subtract, 2=multiply, 3=divide
Operand A (8 bytes): First number
Operand B (8 bytes): Second number
For example, to calculate 5 + 3
:
Operation:
0
(add) →[0, 0, 0, 0, 0, 0, 0, 0]
Operand A:
5
→[5, 0, 0, 0, 0, 0, 0, 0]
Operand B:
3
→[3, 0, 0, 0, 0, 0, 0, 0]
Now, let's build the zk Program
bonsol build --zk-program-path ./calculator-example/zk-program
Step 4: The Solana Program
Let's examine the simple ZK program provided in the repo at solana-program/src/lib.rs
We have a program that uses Bonsol to verify an off-chain addition:
Program Structure and Initialization
This creates a calculator that uses the Bonsol prover network for computations. It imports key
solana_program
modules such asAccountInfo
,Pubkey
, andProgramError
for handling accounts and errors, andborsh
for serializing data structures such asCalculatorState
(tracking program state) andCalculationRecord
(storing calculation details).The
CalculatorInstruction
enum defines four instructions:Initialize
,SubmitCalculation
,GetHistory
, andCallback
.
ZK Calculation and Handling
The
submit_calculation
function prepares a calculation for the Bonsol ZK network by validating the payer, operation (add, subtract, multiply, divide), and owner. It serializes the operation and operands into a 24-byte input for the ZK program and creates a Bonsol instruction withexecute_v1,
including a callback configuration and 100-slot expiration.A pending
CalculationRecord
is stored inCalculatorState
, which is updated and serialized. Theget_history
function logs the calculation count and last calculation details, while the callback function updates theCalculationRecord
with the ZK result.
Build the Code
Run anchor build
to make sure everything builds correctly:
cd solana-program
anchor build
anchor deploy
Step 5: Set Up the Bonsol Calculator Client
cargo run --bin prover
Let's examine the Bonsol calculator client program provided in the repo at zk-program/src/main.rs
The Rust program is a client for submitting calculator execution requests to the Bonsol platform on the Solana blockchain, using the bonsol_interface crate to create execution instructions.
Key Components
Combines operation code and operands into a 24-byte input for the ZK calculator program.
Configures
ExecutionConfig
(disables input hash, enables output forwarding) and CallbackConfig (specifies callback program and extra accounts).Uses
execute_v1
to create a Bonsol execution instruction with the image ID, execution ID, inputs, tip, and expiration.Sends the instruction as a signed transaction using
solana_client.
cd client
cargo build
Step 6: Start the Backend API Server
Firstly, we need to start up the Node.js Server
cd calculator-api
npm install
npm start
Node.js Express server acts as a REST API wrapper for a Rust-based Bonsol calculator client, enabling users to submit arithmetic operations (add, subtract, multiply, divide) to the Bonsol platform on the Solana blockchain.
Endpoints
The core endpoint, POST /calculate
, validates input (operation and operands), generates or uses a provided execution ID, and runs the Rust client with cargo run to submit the calculation to Bonsol via the direct-bonsol method, storing the request status and transaction signature in a Map. Additional endpoints (GET /execution/:id
, /executions
, /health
, /) provide execution status, list all requests, check server health, and display API info.
If the command was successful, you should see the code below

Step 7: Build the Frontend
In this step, we will interact with the calculator with a frontend using the CalculationRequest
and CalculationResponse
that reveals ExecutionStatus
as 'submitted', 'completed', or 'failed' in the file in frontend/src/bonsol-api-client.ts
.
It defines a BonsolApiClient
class that serves as a client for interacting with the Bonsol Calculator REST API, facilitating arithmetic operation submissions to the Bonsol platform on the Solana blockchain.
It provides methods to:
Submit calculations via POST /calculate,
Retrieve execution status with GET /execution/:id,
List all executions using GET /executions
Check API health with GET /health
Lastly, run the frontend client
cd frontend
npm install
npm start
Open
http://localhost:3000
Step 8: Test Application
Run the computation:
Enter numbers and select operation (e.g 25 * 15)
Click "Calculate with ZK"
Wait ~15-30 seconds for ZK proof computation
What it does - submit calculations through a web interface that:
Sends requests to local API server
Submits to Bonsol ZK network for computation
Returns cryptographically verified results
Displays execution IDs and transaction signatures
Example successful execution:
Calculation: 15 × 25 = 375
Execution ID:
calc_1748059174997_35200c8e
Transaction:
5yTzwjn88HTWTPnciBoqpXnj7ouuYZJsRFN8n2GPM9YmjuctidvJkhywepj11dxuXjKvTRC48PXBetL6ERtDb5mF
Note
Here are some ideas if you are interested in extending the capabilities of this client example
Add support for more complex mathematical operations
Implement batch calculations
Add input validation and error handling
Support for floating-point operations (requires ZK program changes)
Add result verification and display
Last updated