miden_client_integration_tests/tests/
config.rs1use std::env::temp_dir;
2use std::path::PathBuf;
3use std::sync::Arc;
4
5use anyhow::{Context, Result};
6use miden_client::builder::ClientBuilder;
7use miden_client::crypto::RpoRandomCoin;
8use miden_client::rpc::{Endpoint, GrpcClient};
9use miden_client::testing::common::{FilesystemKeyStore, TestClient, create_test_store_path};
10use miden_client::{DebugMode, Felt};
11use miden_client_sqlite_store::ClientBuilderSqliteExt;
12use rand::Rng;
13use uuid::Uuid;
14
15#[derive(Debug, Clone)]
16pub struct ClientConfig {
17 pub rpc_endpoint: Endpoint,
18 pub rpc_timeout_ms: u64,
19 pub store_config: PathBuf,
20 pub auth_path: PathBuf,
21}
22
23impl ClientConfig {
24 pub fn new(rpc_endpoint: Endpoint, rpc_timeout_ms: u64) -> Self {
25 Self {
26 rpc_endpoint,
27 rpc_timeout_ms,
28 auth_path: create_test_auth_path(),
29 store_config: create_test_store_path(),
30 }
31 }
32
33 pub fn as_parts(&self) -> (Endpoint, u64, PathBuf, PathBuf) {
34 (
35 self.rpc_endpoint.clone(),
36 self.rpc_timeout_ms,
37 self.store_config.clone(),
38 self.auth_path.clone(),
39 )
40 }
41
42 #[allow(clippy::return_self_not_must_use)]
43 pub fn with_rpc_endpoint(mut self, rpc_endpoint: Endpoint) -> Self {
44 self.rpc_endpoint = rpc_endpoint;
45 self
46 }
47
48 pub fn rpc_endpoint(&self) -> Endpoint {
49 self.rpc_endpoint.clone()
50 }
51
52 pub async fn into_client_builder(
57 self,
58 ) -> Result<(ClientBuilder<FilesystemKeyStore>, FilesystemKeyStore)> {
59 let (rpc_endpoint, rpc_timeout, store_config, auth_path) = self.as_parts();
60
61 let mut rng = rand::rng();
62 let coin_seed: [u64; 4] = rng.random();
63
64 let rng = RpoRandomCoin::new(coin_seed.map(Felt::new).into());
65
66 let keystore = FilesystemKeyStore::new(auth_path.clone()).with_context(|| {
67 format!("failed to create keystore at path: {}", auth_path.to_string_lossy())
68 })?;
69
70 let builder = ClientBuilder::new()
71 .rpc(Arc::new(GrpcClient::new(&rpc_endpoint, rpc_timeout)))
72 .rng(Box::new(rng))
73 .sqlite_store(store_config)
74 .filesystem_keystore(auth_path.to_str().with_context(|| {
75 format!("failed to convert auth path to string: {}", auth_path.to_string_lossy())
76 })?)
77 .in_debug_mode(DebugMode::Disabled)
78 .tx_graceful_blocks(None);
79
80 Ok((builder, keystore))
81 }
82
83 pub async fn into_client(self) -> Result<(TestClient, FilesystemKeyStore)> {
89 let (builder, keystore) = self.into_client_builder().await?;
90
91 let mut client = builder.build().await.with_context(|| "failed to build test client")?;
92
93 client.sync_state().await.with_context(|| "failed to sync client state")?;
94
95 Ok((client, keystore))
96 }
97}
98
99impl Default for ClientConfig {
100 fn default() -> Self {
109 let endpoint = match std::env::var("TEST_MIDEN_RPC_ENDPOINT") {
111 Ok(endpoint) => Endpoint::try_from(endpoint.as_str()).unwrap(),
112 Err(_) => Endpoint::localhost(),
113 };
114
115 let timeout_ms = 10000;
116
117 Self::new(endpoint, timeout_ms)
118 }
119}
120
121pub(crate) fn create_test_auth_path() -> PathBuf {
122 let auth_path = temp_dir().join(format!("keystore-{}", Uuid::new_v4()));
123 std::fs::create_dir_all(&auth_path).unwrap();
124 auth_path
125}