sp1_sdk/blocking/network/builder.rs
1//! # Network Prover Builder (Blocking)
2//!
3//! This module provides a blocking builder for the [`NetworkProver`].
4
5use alloy_primitives::Address;
6use sp1_core_machine::riscv::RiscvAir;
7use sp1_hypercube::Machine;
8use sp1_primitives::SP1Field;
9
10use super::NetworkProver;
11use crate::network::{signer::NetworkSigner, NetworkMode, TEE_NETWORK_RPC_URL};
12
13/// A builder for the blocking [`NetworkProver`].
14///
15/// The builder is used to configure the [`NetworkProver`] before it is built.
16pub struct NetworkProverBuilder {
17 pub(crate) private_key: Option<String>,
18 pub(crate) rpc_url: Option<String>,
19 pub(crate) tee_signers: Option<Vec<Address>>,
20 pub(crate) signer: Option<NetworkSigner>,
21 pub(crate) network_mode: Option<NetworkMode>,
22 pub(crate) hosted: bool,
23 pub(crate) machine: Machine<SP1Field, RiscvAir<SP1Field>>,
24}
25
26impl Default for NetworkProverBuilder {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl NetworkProverBuilder {
33 /// Creates a new [`NetworkProverBuilder`].
34 #[must_use]
35 pub fn new() -> Self {
36 Self::new_with_machine(RiscvAir::machine())
37 }
38
39 /// Creates a new [`NetworkProverBuilder`] with a given machine.
40 #[must_use]
41 pub const fn new_with_machine(machine: Machine<SP1Field, RiscvAir<SP1Field>>) -> Self {
42 Self {
43 private_key: None,
44 rpc_url: None,
45 tee_signers: None,
46 signer: None,
47 network_mode: None,
48 hosted: false,
49 machine,
50 }
51 }
52
53 /// Sets the Secp256k1 private key (same format as the one used by Ethereum).
54 ///
55 /// # Details
56 /// Sets the private key that will be used sign requests sent to the network. By default, the
57 /// private key is read from the `NETWORK_PRIVATE_KEY` environment variable.
58 ///
59 /// # Example
60 /// ```rust,no_run
61 /// use sp1_sdk::blocking::ProverClient;
62 ///
63 /// let prover = ProverClient::builder().network().private_key("...").build();
64 /// ```
65 #[must_use]
66 pub fn private_key(mut self, private_key: &str) -> Self {
67 self.private_key = Some(private_key.to_string());
68 self
69 }
70
71 /// Sets the remote procedure call URL.
72 ///
73 /// # Details
74 /// The URL determines the network that the client will connect to. By default, the URL is
75 /// read from the `NETWORK_RPC_URL` environment variable.
76 ///
77 /// # Example
78 /// ```rust,no_run
79 /// use sp1_sdk::blocking::ProverClient;
80 ///
81 /// let prover = ProverClient::builder().network().rpc_url("...").build();
82 /// ```
83 #[must_use]
84 pub fn rpc_url(mut self, rpc_url: &str) -> Self {
85 self.rpc_url = Some(rpc_url.to_string());
86 self
87 }
88
89 /// Process proofs inside a TEE.
90 ///
91 /// # Details
92 /// In order to keep the inputs private, it is possible to route the proof
93 /// requests to a TEE enclave.
94 ///
95 /// # Example
96 /// ```rust,no_run
97 /// use sp1_sdk::blocking::ProverClient;
98 ///
99 /// let prover = ProverClient::builder().network().private().build();
100 /// ```
101 #[must_use]
102 pub fn private(mut self) -> Self {
103 self.rpc_url = Some(TEE_NETWORK_RPC_URL.to_string());
104 self
105 }
106
107 /// Configures the prover for hosted proving.
108 ///
109 /// # Details
110 /// Hosted proving runs in [`NetworkMode::Reserved`] and makes `prove(&pk, stdin)` skip local
111 /// simulation and use the maximum cycle and gas limits by default, with no network-specific
112 /// toggles required. This matches the behavior expected by self-hosted clusters talking to the
113 /// network-gateway. The defaults remain overridable per request.
114 ///
115 /// # Example
116 /// ```rust,no_run
117 /// use sp1_sdk::blocking::ProverClient;
118 ///
119 /// let prover = ProverClient::builder().network().hosted().build();
120 /// ```
121 #[must_use]
122 pub fn hosted(mut self) -> Self {
123 self.hosted = true;
124 self.network_mode = Some(NetworkMode::Reserved);
125 self
126 }
127
128 /// Sets the list of TEE signers, used for verifying TEE proofs.
129 #[must_use]
130 pub fn tee_signers(mut self, tee_signers: &[Address]) -> Self {
131 self.tee_signers = Some(tee_signers.to_vec());
132 self
133 }
134
135 /// Sets the network signer to use for signing requests.
136 ///
137 /// # Details
138 /// This method allows you to provide a custom signer implementation, such as AWS KMS or
139 /// a local private key signer. If both `signer` and `private_key` are provided, the signer
140 /// takes precedence.
141 #[must_use]
142 pub fn signer(mut self, signer: NetworkSigner) -> Self {
143 self.signer = Some(signer);
144 self
145 }
146
147 /// Builds a blocking [`NetworkProver`].
148 ///
149 /// # Details
150 /// This method will build a [`NetworkProver`] with the given parameters. If `signer` is
151 /// provided, it will be used directly. Otherwise, if `private_key` is provided, a local
152 /// signer will be created from it. If neither is provided, the method will look for the
153 /// `NETWORK_PRIVATE_KEY` environment variable.
154 ///
155 /// # Example
156 /// ```rust,no_run
157 /// use sp1_sdk::blocking::ProverClient;
158 ///
159 /// let prover = ProverClient::builder().network().private_key("...").build();
160 /// ```
161 #[must_use]
162 pub fn build(self) -> NetworkProver {
163 let async_builder = crate::network::builder::NetworkProverBuilder {
164 private_key: self.private_key,
165 rpc_url: self.rpc_url,
166 tee_signers: self.tee_signers,
167 signer: self.signer,
168 network_mode: self.network_mode,
169 hosted: self.hosted,
170 machine: self.machine,
171 };
172 let prover = crate::blocking::block_on(async_builder.build());
173 NetworkProver { prover }
174 }
175}