Skip to main content

Client builders

EmbeddedClientBuilder and RemoteClientBuilder configure the proving backend before constructing a client. Start the chain with ProverClient::embedded() or ProverClient::remote(url), then finalize with .build().

Overview

Builders are never constructed directly. They are returned by:

ProverClient::embedded() // → EmbeddedClientBuilder
ProverClient::remote("https://prover.tld") // → RemoteClientBuilder

Both follow the method-chaining pattern: every configuration method returns Self, so options can be composed in any order. Call .build() at the end to validate the configuration and produce the client.

// Embedded client with the assembly executor and GPU
let client = ProverClient::embedded()
.assembly()
.gpu()
.build()?;

// Remote client with custom timeouts
let client = ProverClient::remote("https://prover.example.com")
.connect_timeout(Duration::from_secs(5))
.request_timeout(Duration::from_secs(600))
.build()?;
Single instance per process

.build() may be called once per process — across both builder kinds. A second call (embedded or remote) panics with A ProverClient already exists. Only one instance is allowed per process. Build the client once at startup and share it via Arc<…>, or for the embedded client by cloning it directly.


EmbeddedClientBuilder

Builds an EmbeddedClient that runs the prover in your process.

Executor selection

Controls how the guest ELF is re-executed to build the witness.

MethodEffect
.emulator()Use the software emulator. Default. Works on every platform.
.assembly()Use the native ASM execution engine. Linux x86_64 only. Faster.
.executor(ExecutorKind)Set the executor explicitly. ExecutorKind::Emulator (default) or ExecutorKind::Assembly.

Device selection

MethodEffect
.gpu()Enable GPU acceleration. Has no effect (and silently falls back) when no CUDA device is present.

.gpu() takes no argument — it is a flag setter. CPU is the default whenever .gpu() is not chained; there is no explicit .cpu() method.

Proving keys

MethodEffect
.proving_key(path: impl Into<PathBuf>)Override the directory containing the STARK proving key.
.proving_key_plonk(path: impl Into<PathBuf>)Override the directory containing the PLONK proving key.

Proof kind

MethodEffect
.plonk()Switch the default proof kind to ProofKind::Plonk.

.plonk() only sets the proof kind. It does not eagerly load the PLONK proving key.

Diagnostics

MethodEffect
.verbose(level: u8)Set log verbosity. 0 is quiet (default); higher values emit more detail.

Runtime options

Two options structs configure the runtime behaviour of an embedded client. Build each one with its chainable setters and apply it with the corresponding .with_* method:

MethodEffect
.with_embedded_opts(opts: EmbeddedOpts)Set proving-side tuning (memory caps, thread counts, key paths, PLONK preload). See EmbeddedOpts.
.asm_options(opts: AsmOptions)Pass extra options to the Assembly executor — requires .assembly(). See AsmOptions.

If .asm_options(...) is set but the executor is not Assembly, .build() panics. If both the builder and EmbeddedOpts set a value for the STARK or PLONK key path, the builder-level .proving_key(...) / .proving_key_plonk(...) win on .build().

Build

MethodReturns
.build()Result<EmbeddedClient>

.build() validates the configuration and returns an error for unsupported combinations (e.g. .assembly() on a non-Linux-x86_64 host, or .gpu() with no CUDA toolkit available). It also panics if a ProverClient already exists in the process or if .asm_options(...) is set without the Assembly executor.

Example

use std::path::PathBuf;
use zisk_sdk::{EmbeddedOpts, ProverClient};

let opts = EmbeddedOpts::default();

let client = ProverClient::embedded()
.assembly()
.gpu()
.proving_key("/data/keys/stark")
.proving_key_plonk("/data/keys/plonk")
.plonk()
.with_embedded_opts(opts)
.build()?;

EmbeddedOpts

Runtime tuning options applied via .with_embedded_opts(...). Every field has a corresponding builder-style setter on EmbeddedOpts itself, so options can be chained from EmbeddedOpts::default().

pub struct EmbeddedOpts {
pub minimal_memory: bool,
pub proving_key: Option<PathBuf>,
pub proving_key_snark: Option<PathBuf>,
pub preload_plonk: bool,
pub max_witness_stored: Option<usize>,
pub number_threads_witness: Option<usize>,
pub max_streams: Option<usize>,
}
FieldTypeDescription
minimal_memoryboolReduce memory footprint during proving at the cost of speed.
proving_keyOption<PathBuf>STARK proving key directory.
proving_key_snarkOption<PathBuf>PLONK/SNARK proving key directory.
preload_plonkboolEagerly load PLONK/SNARK keys at startup instead of on first use.
max_witness_storedOption<usize>Maximum bytes held for intermediate witness data.
number_threads_witnessOption<usize>Number of threads dedicated to witness generation.
max_streamsOption<usize>Maximum parallel streams during proving.

Setters

MethodSets
.minimal_memory()minimal_memory = true
.proving_key(path: impl Into<PathBuf>)proving_key = Some(...)
.proving_key_snark(path: impl Into<PathBuf>)proving_key_snark = Some(...)
.preload_plonk()preload_plonk = true
.max_witness_stored(max: usize)max_witness_stored = Some(max)
.number_threads_witness(threads: usize)number_threads_witness = Some(threads)
.max_streams(max: usize)max_streams = Some(max)
use zisk_sdk::EmbeddedOpts;

let opts = EmbeddedOpts::default()
.minimal_memory()
.preload_plonk()
.number_threads_witness(16)
.max_streams(4);

AsmOptions

Configuration for the native ASM executor, applied via .asm_options(...). Re-exported by zisk_sdk from the prover backend.

pub struct AsmOptions {
pub asm_path: Option<PathBuf>,
pub no_auto_setup: bool,
pub unlock_mapped_memory: bool,
pub asm_out_file: bool,
pub is_distributed: bool,
}
FieldTypeDescription
asm_pathOption<PathBuf>Override the path of the precompiled ASM binary.
no_auto_setupboolSkip the implicit setup pass before proving.
unlock_mapped_memoryboolDisable mlock on memory-mapped regions used by the runner.
asm_out_fileboolHave the ASM runner write its output to a file instead of shared memory.
is_distributedboolMark the runner as participating in a distributed (MPI) proving session.

Setters

MethodSets
.asm_path(path: impl Into<PathBuf>)asm_path = Some(...)
.no_auto_setup()no_auto_setup = true
.unlock_mapped_memory()unlock_mapped_memory = true
.asm_out_file()asm_out_file = true
.is_distributed()is_distributed = true
use zisk_sdk::AsmOptions;

let asm = AsmOptions::default()
.asm_path("/data/asm/zisk-runner")
.unlock_mapped_memory();

RemoteClientBuilder

Builds a RemoteClient that delegates proving to an external coordinator over the network. The remote builder surface is deliberately small: the executor, device, key paths, and ASM options all live on the coordinator, not the client.

Constructor

ProverClient::remote(url: impl Into<String>) -> RemoteClientBuilder
ParameterTypeDescription
urlimpl Into<String>Full base URL of the remote coordinator.

Timeouts

MethodDefaultDescription
.connect_timeout(d: Duration)10 sTimeout for establishing the underlying connection.
.request_timeout(d: Duration)300 sTimeout applied to a full request round-trip.

Setting request_timeout too low causes long proving jobs to error out even though the prover is still running. Set it well above your expected proof time.

Build

MethodReturns
.build()Result<RemoteClient>

.build() opens a connection to the coordinator. It is also subject to the single-instance-per-process invariant — see the warning at the top of this page.

Example

use std::time::Duration;
use zisk_sdk::ProverClient;

let client = ProverClient::remote("https://prover.example.com")
.connect_timeout(Duration::from_secs(5))
.request_timeout(Duration::from_secs(900))
.build()?;