@@ -8,7 +8,7 @@ use miden_tx::ExecutionOptions;
88use miden_tx:: auth:: TransactionAuthenticator ;
99use rand:: Rng ;
1010
11- use crate :: keystore:: FilesystemKeyStore ;
11+ use crate :: keystore:: { EncryptionKeyStore , FilesystemKeyStore } ;
1212use crate :: note_transport:: NoteTransportClient ;
1313use crate :: rpc:: NodeRpcClient ;
1414use crate :: store:: { Store , StoreError } ;
@@ -36,6 +36,16 @@ enum AuthenticatorConfig<AUTH> {
3636 Instance ( Arc < AUTH > ) ,
3737}
3838
39+ /// Represents the configuration for an encryption keystore.
40+ ///
41+ /// This enum defers encryption keystore instantiation until the build phase.
42+ enum EncryptionKeystoreConfig {
43+ /// Use a filesystem keystore at the given path.
44+ Path ( String ) ,
45+ /// Use a custom encryption keystore instance.
46+ Instance ( Arc < dyn EncryptionKeyStore + Send + Sync > ) ,
47+ }
48+
3949// STORE BUILDER
4050// ================================================================================================
4151
@@ -59,8 +69,7 @@ pub trait StoreFactory {
5969/// A builder for constructing a Miden client.
6070///
6171/// This builder allows you to configure the various components required by the client, such as the
62- /// RPC endpoint, store, RNG, and keystore. It is generic over the keystore type. By default, it
63- /// uses `FilesystemKeyStore<rand::rngs::StdRng>`.
72+ /// RPC endpoint, store, RNG, and keystore. It is generic over the authenticator type.
6473pub struct ClientBuilder < AUTH > {
6574 /// An optional custom RPC client. If provided, this takes precedence over `rpc_endpoint`.
6675 rpc_api : Option < Arc < dyn NodeRpcClient > > ,
@@ -70,6 +79,8 @@ pub struct ClientBuilder<AUTH> {
7079 rng : Option < Box < dyn FeltRng > > ,
7180 /// The keystore configuration provided by the user.
7281 keystore : Option < AuthenticatorConfig < AUTH > > ,
82+ /// The encryption keystore configuration.
83+ encryption_keystore : Option < EncryptionKeystoreConfig > ,
7384 /// A flag to enable debug mode.
7485 in_debug_mode : DebugMode ,
7586 /// The number of blocks that are considered old enough to discard pending transactions. If
@@ -91,6 +102,7 @@ impl<AUTH> Default for ClientBuilder<AUTH> {
91102 store : None ,
92103 rng : None ,
93104 keystore : None ,
105+ encryption_keystore : None ,
94106 in_debug_mode : DebugMode :: Disabled ,
95107 tx_graceful_blocks : Some ( TX_GRACEFUL_BLOCKS ) ,
96108 max_block_number_delta : None ,
@@ -154,6 +166,16 @@ where
154166 self
155167 }
156168
169+ /// Optionally provide a custom encryption keystore instance.
170+ #[ must_use]
171+ pub fn encryption_keystore < ENC > ( mut self , keystore : Arc < ENC > ) -> Self
172+ where
173+ ENC : EncryptionKeyStore + Send + Sync + ' static ,
174+ {
175+ self . encryption_keystore = Some ( EncryptionKeystoreConfig :: Instance ( keystore) ) ;
176+ self
177+ }
178+
157179 /// Optionally set a maximum number of blocks that the client can be behind the network.
158180 /// By default, there's no maximum.
159181 #[ must_use]
@@ -175,9 +197,11 @@ where
175197 ///
176198 /// This stores the keystore path as a configuration option so that actual keystore
177199 /// initialization is deferred until `build()`. This avoids panicking during builder chaining.
200+ /// The same directory will be used for both authentication and encryption keys.
178201 #[ must_use]
179202 pub fn filesystem_keystore ( mut self , keystore_path : & str ) -> Self {
180203 self . keystore = Some ( AuthenticatorConfig :: Path ( keystore_path. to_string ( ) ) ) ;
204+ self . encryption_keystore = Some ( EncryptionKeystoreConfig :: Path ( keystore_path. to_string ( ) ) ) ;
181205 self
182206 }
183207
@@ -241,16 +265,29 @@ where
241265 Some ( AuthenticatorConfig :: Path ( ref path) ) => {
242266 let keystore = FilesystemKeyStore :: new ( path. into ( ) )
243267 . map_err ( |err| ClientError :: ClientInitializationError ( err. to_string ( ) ) ) ?;
244- Some ( Arc :: new ( AUTH :: from ( keystore) ) )
268+ Some ( Arc :: new ( AUTH :: from_keystore ( keystore) ) )
245269 } ,
246270 None => None ,
247271 } ;
248272
273+ // Initialize the encryption keystore.
274+ let encryption_keystore: Option < Arc < dyn EncryptionKeyStore + Send + Sync > > =
275+ match self . encryption_keystore {
276+ Some ( EncryptionKeystoreConfig :: Instance ( ks) ) => Some ( ks) ,
277+ Some ( EncryptionKeystoreConfig :: Path ( ref path) ) => {
278+ let keystore = FilesystemKeyStore :: new ( path. into ( ) )
279+ . map_err ( |err| ClientError :: ClientInitializationError ( err. to_string ( ) ) ) ?;
280+ Some ( Arc :: new ( keystore) )
281+ } ,
282+ None => None ,
283+ } ;
284+
249285 Client :: new (
250286 rpc_api,
251287 rng,
252288 store,
253289 authenticator,
290+ encryption_keystore,
254291 ExecutionOptions :: new (
255292 Some ( MAX_TX_EXECUTION_CYCLES ) ,
256293 MIN_TX_EXECUTION_CYCLES ,
@@ -271,12 +308,14 @@ where
271308// ================================================================================================
272309
273310/// Marker trait to capture the bounds the builder requires for the authenticator type
274- /// parameter
275- pub trait BuilderAuthenticator :
276- TransactionAuthenticator + From < FilesystemKeyStore < rand :: rngs :: StdRng > > + ' static
277- {
311+ /// parameter.
312+ pub trait BuilderAuthenticator : TransactionAuthenticator + ' static {
313+ /// Creates an authenticator from a `FilesystemKeyStore`.
314+ fn from_keystore ( keystore : FilesystemKeyStore < rand :: rngs :: StdRng > ) -> Self ;
278315}
279- impl < T > BuilderAuthenticator for T where
280- T : TransactionAuthenticator + From < FilesystemKeyStore < rand:: rngs:: StdRng > > + ' static
281- {
316+
317+ impl BuilderAuthenticator for FilesystemKeyStore < rand:: rngs:: StdRng > {
318+ fn from_keystore ( keystore : FilesystemKeyStore < rand:: rngs:: StdRng > ) -> Self {
319+ keystore
320+ }
282321}
0 commit comments