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_ext()Result<RemoteClientExt>

.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.

.build_ext() connects the same way but returns a RemoteClientExt, whose execute and prove builders accept opaque job-level .metadata(key, value) pairs. It dereferences to RemoteClient, so nothing else changes. There is no embedded counterpart — EmbeddedClientBuilder has no build_ext().

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()?;