Public Bindings API
This header file defines the core public API for Colibri's stateless Ethereum proof generation and verification system. It serves as the primary interface for language bindings (TypeScript, Python, Kotlin, Swift, etc.) and native C applications.
Overview
Colibri implements a stateless light client for Ethereum that can generate and verify cryptographic proofs for JSON-RPC method calls without maintaining blockchain state. The API provides:
Proof Generation: Create cryptographic proofs for Ethereum RPC calls
Proof Verification: Verify proofs and extract verified results
Asynchronous Execution: Non-blocking request handling with external data fetching
Multi-Chain Support: Works with Ethereum mainnet, testnets, and L2s
Language Bindings: Clean C API designed for easy FFI integration
Architecture
Stateless Design
Unlike traditional Ethereum nodes that maintain the full blockchain state, Colibri operates statelessly by:
Requesting only necessary data from external sources (RPC nodes, beacon chain APIs)
Building cryptographic proofs from Merkle proofs and beacon chain sync committee signatures
Verifying against trusted checkpoints without storing any state
This design allows Colibri to run efficiently in constrained environments (browsers, mobile devices, IoT) while providing the same security guarantees as a full node.
Asynchronous Execution Model
The API implements an asynchronous state machine where the C library cannot perform network I/O directly. Instead, the host system (JavaScript runtime, Python process, JVM, etc.) is responsible for executing HTTP requests.
Execution Flow

This design allows the host system to use native async technologies (Promises in JavaScript, async/await in Python, coroutines in Kotlin) while keeping the C core synchronous and portable.
Host System Responsibilities
The host system (language binding or application using this API) has several critical responsibilities:
1. Configuration and Node Management
The host system must maintain lists of data source endpoints for each chain:
Ethereum RPC nodes (
type: "eth_rpc"): For execution layer dataBeacon API nodes (
type: "beacon_api"): For consensus layer dataCheckpointz servers (
type: "checkpointz"): For trusted sync committee checkpointsProver servers (
type: "prover"): Optional centralized proof generation
Example Configuration:
2. Request Execution with Retry Logic
When c4_prover_execute_json_status() or c4_verify_execute_json_status() returns "status": "pending", the host system must execute all pending requests. For each request in the "requests" array:
Step 1: Select Node
Choose a node from the appropriate list based on request.type:
"eth_rpc"→ use Ethereum RPC nodes"beacon_api"→ use Beacon API nodes"checkpointz"→ use Checkpointz servers
Step 2: Apply Filters
Skip excluded nodes: If
(request.exclude_mask & (1 << node_index)) != 0, skip this nodePrefer client types: If
request.preferred_client_type != 0, prefer matching beacon clients
Step 3: Build HTTP Request
Method: Use
request.method(usually "GET" or "POST")URL: Construct as
server_base_url + "/" + request.urlHeaders:
Content-Type:"application/json"ifrequest.payloadis presentAccept:"application/octet-stream"ifrequest.encoding == "ssz", else"application/json"
Body: Use
request.payloadas JSON for POST requests
Step 4: Retry Logic
If a request fails:
Try the next node in the list (respecting
exclude_mask)If all nodes fail, call
c4_req_set_error(request.req_ptr, error_message, 0)
If a request succeeds:
Call
c4_req_set_response(request.req_ptr, response_data, node_index)
Step 5: Parallel Execution
For optimal performance, execute all pending requests in parallel using the host language's async capabilities (Promise.all, asyncio.gather, etc.).
3. Memory Management
Allocated strings: All strings returned from C functions (JSON status strings) must be freed by the host
Context cleanup: Always call
c4_free_prover_ctx()orc4_verify_free_ctx()when doneRequest data: Data passed to
c4_req_set_response()is copied by the C libraryError strings: Error strings passed to
c4_req_set_error()are copied by the C library
4. Error Handling
The host system should handle:
Network errors: Retry with different nodes
HTTP errors: Check status codes, parse JSON-RPC error responses
Timeouts: Implement reasonable timeouts (30s recommended)
Invalid responses: Validate response format before calling
c4_req_set_response()
Data Request Structure
When the status is "pending", the "requests" array contains objects with:
req_ptr
number
Opaque pointer to pass to c4_req_set_response() or c4_req_set_error()
chain_id
number
Chain ID for this request
type
string
Request type: "eth_rpc", "beacon_api", "checkpointz", "rest_api"
encoding
string
Response encoding: "json" or "ssz"
method
string
HTTP method: "get", "post", "put", "delete"
url
string
URL path to append to server base URL
payload
object?
Optional JSON payload for POST/PUT requests
exclude_mask
number
Bitmask of nodes to exclude (bit N = exclude node N)
preferred_client_type
number
Preferred beacon client type (0 = any)
Method Support
Not all Ethereum RPC methods can be proven. Use c4_get_method_support() to check:
1
PROOFABLE
Method can be proven (use proof flow)
2
UNPROOFABLE
Method exists but cannot be proven (call RPC directly)
3
NOT_SUPPORTED
Method not supported by Colibri
4
LOCAL
Method can be computed locally (no network needed)
Proofable methods include:
eth_getBalance,eth_getCode,eth_getStorageAteth_getTransactionByHash,eth_getTransactionReceipteth_getBlockByHash,eth_getBlockByNumbereth_getLogs,eth_call,eth_getProof
Local methods include:
eth_chainId,net_version
Complete Usage Examples
These examples show how to call the C functions directly from different host languages. This is useful for developers creating new language bindings or integrating Colibri into existing applications.
Note: These examples are simplified for clarity. In production code, you should:
Use proper JSON parsing libraries (not string matching)
Implement robust error handling and retry logic
Handle memory management carefully (especially in C/manual memory languages)
Execute pending requests in parallel for optimal performance
Implement proper node selection and exclusion mask handling
Best Practices
Performance Optimization
Parallel Request Execution: Always execute pending requests in parallel
Connection Pooling: Reuse HTTP connections across requests
Response Caching: Cache responses based on request URL and payload (respect TTL)
Node Selection: Track node reliability and prefer faster/more reliable nodes
Error Handling
Retry with Backoff: Implement exponential backoff for transient errors
Fallback Nodes: Always configure multiple nodes per data source type
Timeout Handling: Use reasonable timeouts (30s recommended)
Graceful Degradation: Fall back to direct RPC for UNPROOFABLE methods
Security Considerations
Trusted Checkpoint: Always configure a trusted checkpoint for initial sync
Node Diversity: Use nodes from different operators to prevent eclipse attacks
Response Validation: Validate response formats before passing to C library
Memory Safety: Always free returned strings and contexts
c4_create_prover_ctx
Creates a new prover context for generating a proof.
This function initializes the proof generation process for a specific Ethereum RPC method. The returned context must be used with c4_prover_execute_json_status() to drive the asynchronous proof generation process.
Memory Management: The caller is responsible for freeing the returned context using c4_free_prover_ctx() when done.
Example:
Parameters
method: The Ethereum RPC method to prove (e.g., "eth_getBalance", "eth_getBlockByHash")params: The method parameters as a JSON array string (e.g., '["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest"]')chain_id: The blockchain chain ID (1 = Ethereum Mainnet, 11155111 = Sepolia, etc.)flags: Flags to customize proof generation:
Returns
A new prover context pointer, or NULL if creation failed
c4_prover_execute_json_status
Executes one step of the proof generation state machine.
This function drives the asynchronous proof generation process. Call it repeatedly in a loop until it returns a status of "success" or "error". When it returns "pending", the host system must handle the pending data requests before calling this function again.
Memory Management: The returned JSON string must be freed by the caller using free().
Return Value Format:
The function returns a JSON string with one of three possible statuses:
Success (proof generation complete):
result: Hexadecimal string pointer to proof data (use withc4_prover_get_proof())result_len: Length of the proof in bytes
Error (proof generation failed):
error: Human-readable error message
Pending (waiting for external data):
requests: Array of data requests that must be fulfilled (see "Data Request Structure" in API docs)
Example Usage:
Parameters
ctx: The prover context created byc4_create_prover_ctx()
Returns
A JSON string describing the current status (see format below)
c4_prover_get_proof
Retrieves the generated proof from a completed prover context.
This function should only be called after c4_prover_execute_json_status() returns a status of "success". The proof data is owned by the context and remains valid until c4_free_prover_ctx() is called.
Memory Management: The returned bytes_t.data pointer is owned by the context. Do NOT call free() on it. Copy the data if you need to retain it after freeing the context.
Example:
Parameters
ctx: The prover context (must be in "success" state)
Returns
A bytes_t structure containing the proof data
c4_free_prover_ctx
Frees all resources associated with a prover context.
This function must be called to clean up a prover context created by c4_create_prover_ctx(). After calling this function, the context pointer is invalid and must not be used.
Memory Management: This frees the context and all associated internal memory, including the proof data. If you need the proof data after freeing the context, copy it first using c4_prover_get_proof().
Example:
Parameters
ctx: The prover context to free (may be NULL, in which case this is a no-op)
c4_req_set_response
Sets the successful response data for a pending data request.
When c4_prover_execute_json_status() or c4_verify_execute_json_status() returns "status": "pending", the host system must fetch the data for each request and call this function to provide the response. After all pending requests are fulfilled, call the execute function again to continue processing.
Memory Management: The data is copied by this function. The caller retains ownership of the input data and is responsible for freeing it if needed.
Example:
Parameters
req_ptr: Opaque request pointer from the "req_ptr" field in the JSON statusdata: The response data as bytes_t (will be copied)node_index: Index of the node that provided this response (0-15, used for exclude_mask)
c4_req_set_error
Sets an error for a pending data request.
When a data request cannot be fulfilled (network error, all nodes failed, invalid response), call this function to report the error. The proof generation/verification will typically fail with this error message, or may retry with different parameters.
Memory Management: The error string is copied by this function. The caller retains ownership and is responsible for freeing it if needed.
Example:
Parameters
req_ptr: Opaque request pointer from the "req_ptr" field in the JSON statuserror: Error message string (will be copied)node_index: Index of the node that failed (0-15), or 0 if all nodes failed
c4_verify_create_ctx
Creates a verification context for verifying a proof.
This function initializes the proof verification process. The returned context must be used with c4_verify_execute_json_status() to drive the asynchronous verification process.
Verification may require additional data from external sources (e.g., beacon chain finality updates, sync committee data), so it follows the same asynchronous execution model as proof generation.
Memory Management: The caller is responsible for freeing the returned context using c4_verify_free_ctx() when done.
Trusted Checkpoints:
A trusted checkpoint is a 32-byte hash of a beacon chain block root that is assumed to be correct. Colibri uses this checkpoint as the starting point for verification, avoiding the need to sync from genesis.
Format:
"0x" + 64 hex characters(66 characters total)Recommended: Use a recent finalized beacon block root from a trusted source
If NULL: Uses the built-in checkpoint for the chain (may be outdated)
Example:
Parameters
proof: The proof data to verifymethod: The Ethereum RPC method that was proven (e.g., "eth_getBalance")args: The method arguments as JSON array string (must match proof)chain_id: The blockchain chain ID (must match proof)trusted_checkpoint: Optional trusted checkpoint as hex string (0x-prefixed, 66 chars),
Returns
A new verification context pointer, or NULL if creation failed
c4_verify_execute_json_status
Executes one step of the proof verification state machine.
This function drives the asynchronous proof verification process. Call it repeatedly in a loop until it returns a status of "success" or "error". When it returns "pending", the host system must handle the pending data requests before calling this function again.
The execution flow is identical to c4_prover_execute_json_status(), but returns the verified result instead of a proof.
Memory Management: The returned JSON string must be freed by the caller using free().
Return Value Format:
Success (verification complete):
Error (verification failed):
Pending (waiting for external data):
Example Usage:
Parameters
ctx: The verification context created byc4_verify_create_ctx()
Returns
A JSON string describing the current status (see format below)
c4_verify_free_ctx
Frees all resources associated with a verification context.
This function must be called to clean up a verification context created by c4_verify_create_ctx(). After calling this function, the context pointer is invalid and must not be used.
Example:
Parameters
ctx: The verification context to free (may be NULL, in which case this is a no-op)
c4_get_method_support
Queries whether a specific RPC method is supported and how it should be handled.
Not all Ethereum RPC methods can be cryptographically proven. This function returns information about method support, allowing the host system to decide how to handle each RPC call.
Return Values:
1
PROOFABLE
Method can be cryptographically proven
Use proof generation and verification flow
2
UNPROOFABLE
Method exists but cannot be proven
Call RPC node directly without proof
3
NOT_SUPPORTED
Method is not supported by Colibri
Return error to caller
4
LOCAL
Method can be computed locally
Use verification with empty proof
0
UNKNOWN
Unknown method or error
Treat as NOT_SUPPORTED
Proofable Methods (return 1):
State queries:
eth_getBalance,eth_getCode,eth_getStorageAt,eth_getProofTransaction queries:
eth_getTransactionByHash,eth_getTransactionReceipt,eth_getTransactionByBlockHashAndIndex,eth_getTransactionByBlockNumberAndIndexBlock queries:
eth_getBlockByHash,eth_getBlockByNumber,eth_getBlockTransactionCountByHash,eth_getBlockTransactionCountByNumberLog queries:
eth_getLogsCall simulation:
eth_call,eth_estimateGas
Unproofable Methods (return 2):
Mempool:
eth_sendTransaction,eth_sendRawTransaction,eth_getTransactionCount(pending)Mining:
eth_mining,eth_hashrate,eth_getWork,eth_submitWorkNetwork:
net_listening,net_peerCount
Local Methods (return 4):
eth_chainId: Returns the configured chain IDnet_version: Returns the network version (same as chain ID)
Example:
Parameters
chain_id: The blockchain chain ID to checkmethod: The Ethereum RPC method name (e.g., "eth_getBalance")
Returns
Method support type (see table below)
Last updated